summaryrefslogtreecommitdiff
path: root/gi
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2017-07-12 08:35:07 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2017-07-12 08:35:08 +0900
commitdf82aa0a770d4b3e52e96eb5c60b528ddcdb2343 (patch)
treebbf6d1c2270fe7057773ff1c2cf578ff40f704da /gi
parent095413828bd9b33e57b352f9ca80473172611202 (diff)
downloadpygobject2-df82aa0a770d4b3e52e96eb5c60b528ddcdb2343.tar.gz
pygobject2-df82aa0a770d4b3e52e96eb5c60b528ddcdb2343.tar.bz2
pygobject2-df82aa0a770d4b3e52e96eb5c60b528ddcdb2343.zip
Imported Upstream version 2.26.0upstream/2.26.0
Change-Id: I616aeca320e366d54dd6e188c260b64639305c49 Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'gi')
-rw-r--r--gi/Makefile.am30
-rw-r--r--gi/Makefile.in56
-rw-r--r--gi/gimodule.c93
-rw-r--r--gi/importer.py26
-rw-r--r--gi/module.py64
-rw-r--r--gi/overrides/GIMarshallingTests.py2
-rw-r--r--gi/overrides/GLib.py165
-rw-r--r--gi/overrides/Gdk.py69
-rw-r--r--gi/overrides/Gtk.py49
-rw-r--r--gi/overrides/Makefile.am1
-rw-r--r--gi/overrides/Makefile.in2
-rw-r--r--gi/pygi-argument.c388
-rw-r--r--gi/pygi-argument.h12
-rw-r--r--gi/pygi-boxed.c94
-rw-r--r--gi/pygi-boxed.h10
-rw-r--r--gi/pygi-callbacks.c11
-rw-r--r--gi/pygi-closure.c34
-rw-r--r--gi/pygi-foreign-cairo.c47
-rw-r--r--gi/pygi-foreign-gvariant.c63
-rw-r--r--gi/pygi-foreign-gvariant.h41
-rw-r--r--gi/pygi-foreign.c119
-rw-r--r--gi/pygi-foreign.h15
-rw-r--r--gi/pygi-info.c190
-rw-r--r--gi/pygi-invoke.c333
-rw-r--r--gi/pygi-private.h24
-rw-r--r--gi/pygi-property.c345
-rw-r--r--gi/pygi-property.h39
-rw-r--r--gi/pygi-repository.c99
-rw-r--r--gi/pygi-struct.c55
-rw-r--r--gi/pygi-type.c15
-rw-r--r--gi/pygi-type.h2
-rw-r--r--gi/pygi.h67
-rw-r--r--gi/repository/Makefile.in1
-rw-r--r--gi/types.py15
34 files changed, 1734 insertions, 842 deletions
diff --git a/gi/Makefile.am b/gi/Makefile.am
index c651c97..2fbb4ac 100644
--- a/gi/Makefile.am
+++ b/gi/Makefile.am
@@ -7,7 +7,7 @@ SUBDIRS = \
repository \
overrides
-INCLUDES = -I$(top_srcdir)/gobject
+INCLUDES = -I$(top_srcdir)/gobject -I$(top_srcdir)/glib
pygidir = $(pkgpyexecdir)/gi
pygi_PYTHON = \
@@ -22,7 +22,7 @@ _gi_la_CFLAGS = \
_gi_la_LDFLAGS = \
-module \
-avoid-version \
- -export-symbols-regex init_gi
+ -export-symbols-regex "init_gi|PyInit__gi"
_gi_la_LIBADD = \
$(GI_LIBS)
_gi_la_SOURCES = \
@@ -34,6 +34,8 @@ _gi_la_SOURCES = \
pygi-invoke.h \
pygi-foreign.c \
pygi-foreign.h \
+ pygi-foreign-gvariant.c \
+ pygi-foreign-gvariant.h \
pygi-struct.c \
pygi-struct.h \
pygi-argument.c \
@@ -48,6 +50,8 @@ _gi_la_SOURCES = \
pygi-callbacks.h \
pygi.h \
pygi-private.h \
+ pygi-property.c \
+ pygi-property.h \
pygobject-external.h \
gimodule.c
@@ -58,24 +62,28 @@ _gi_cairo_la_CFLAGS = \
_gi_cairo_la_LDFLAGS = \
-module \
-avoid-version \
- -export-symbols-regex init_gi_cairo
+ -export-symbols-regex "init_gi_cairo|PyInit__gi_cairo"
_gi_cairo_la_LIBADD = \
$(GI_LIBS) \
$(PYCAIRO_LIBS)
_gi_cairo_la_SOURCES = pygi-foreign-cairo.c
-pygi_LTLIBRARIES = _gi.la _gi_cairo.la
+
+pygi_LTLIBRARIES = _gi.la
+
+if ENABLE_CAIRO
+pygi_LTLIBRARIES += _gi_cairo.la
+endif
+
# This is to ensure we have a symlink to the .so in the
# build directory, which the Python interpreter can load
# directly without having to know how to parse .la files.
-_gi.so: _gi.la
- rm -f $@ && $(LN_S) .libs/$@ $@
-_gi_cairo.so: _gi_cairo.la
- rm -f $@ && $(LN_S) .libs/$@ $@
+.la.so:
+ test -L $@ || $(LN_S) .libs/$@ $@
-all-local: _gi.so _gi_cairo.so
-check-local: _gi.so _gi_cairo.so
+all-local: $(LTLIBRARIES:.la=.so)
+check-local: $(LTLIBRARIES:.la=.so)
clean-local:
- rm -f _gi.so _gi_cairo.so
+ rm -f $(LTLIBRARIES:.la=.so)
diff --git a/gi/Makefile.in b/gi/Makefile.in
index 6fb0b9a..1aecd0a 100644
--- a/gi/Makefile.in
+++ b/gi/Makefile.in
@@ -33,6 +33,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@ENABLE_CAIRO_TRUE@am__append_1 = _gi_cairo.la
subdir = gi
DIST_COMMON = $(pygi_PYTHON) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
@@ -75,9 +76,10 @@ am__DEPENDENCIES_1 =
_gi_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am__gi_la_OBJECTS = _gi_la-pygi-repository.lo _gi_la-pygi-info.lo \
_gi_la-pygi-invoke.lo _gi_la-pygi-foreign.lo \
- _gi_la-pygi-struct.lo _gi_la-pygi-argument.lo \
- _gi_la-pygi-type.lo _gi_la-pygi-boxed.lo \
- _gi_la-pygi-closure.lo _gi_la-pygi-callbacks.lo \
+ _gi_la-pygi-foreign-gvariant.lo _gi_la-pygi-struct.lo \
+ _gi_la-pygi-argument.lo _gi_la-pygi-type.lo \
+ _gi_la-pygi-boxed.lo _gi_la-pygi-closure.lo \
+ _gi_la-pygi-callbacks.lo _gi_la-pygi-property.lo \
_gi_la-gimodule.lo
_gi_la_OBJECTS = $(am__gi_la_OBJECTS)
AM_V_lt = $(am__v_lt_$(V))
@@ -93,6 +95,7 @@ _gi_cairo_la_OBJECTS = $(am__gi_cairo_la_OBJECTS)
_gi_cairo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(_gi_cairo_la_CFLAGS) \
$(CFLAGS) $(_gi_cairo_la_LDFLAGS) $(LDFLAGS) -o $@
+@ENABLE_CAIRO_TRUE@am__gi_cairo_la_rpath = -rpath $(pygidir)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -199,6 +202,7 @@ GIOUNIX_LIBS = @GIOUNIX_LIBS@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
GI_CFLAGS = @GI_CFLAGS@
+GI_DATADIR = @GI_DATADIR@
GI_LIBS = @GI_LIBS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
@@ -323,7 +327,7 @@ SUBDIRS = \
repository \
overrides
-INCLUDES = -I$(top_srcdir)/gobject
+INCLUDES = -I$(top_srcdir)/gobject -I$(top_srcdir)/glib
pygidir = $(pkgpyexecdir)/gi
pygi_PYTHON = \
types.py \
@@ -338,7 +342,7 @@ _gi_la_CFLAGS = \
_gi_la_LDFLAGS = \
-module \
-avoid-version \
- -export-symbols-regex init_gi
+ -export-symbols-regex "init_gi|PyInit__gi"
_gi_la_LIBADD = \
$(GI_LIBS)
@@ -352,6 +356,8 @@ _gi_la_SOURCES = \
pygi-invoke.h \
pygi-foreign.c \
pygi-foreign.h \
+ pygi-foreign-gvariant.c \
+ pygi-foreign-gvariant.h \
pygi-struct.c \
pygi-struct.h \
pygi-argument.c \
@@ -366,6 +372,8 @@ _gi_la_SOURCES = \
pygi-callbacks.h \
pygi.h \
pygi-private.h \
+ pygi-property.c \
+ pygi-property.h \
pygobject-external.h \
gimodule.c
@@ -377,18 +385,18 @@ _gi_cairo_la_CFLAGS = \
_gi_cairo_la_LDFLAGS = \
-module \
-avoid-version \
- -export-symbols-regex init_gi_cairo
+ -export-symbols-regex "init_gi_cairo|PyInit__gi_cairo"
_gi_cairo_la_LIBADD = \
$(GI_LIBS) \
$(PYCAIRO_LIBS)
_gi_cairo_la_SOURCES = pygi-foreign-cairo.c
-pygi_LTLIBRARIES = _gi.la _gi_cairo.la
+pygi_LTLIBRARIES = _gi.la $(am__append_1)
all: all-recursive
.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
+.SUFFIXES: .c .la .lo .o .obj .so
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -453,7 +461,7 @@ clean-pygiLTLIBRARIES:
_gi.la: $(_gi_la_OBJECTS) $(_gi_la_DEPENDENCIES)
$(AM_V_CCLD)$(_gi_la_LINK) -rpath $(pygidir) $(_gi_la_OBJECTS) $(_gi_la_LIBADD) $(LIBS)
_gi_cairo.la: $(_gi_cairo_la_OBJECTS) $(_gi_cairo_la_DEPENDENCIES)
- $(AM_V_CCLD)$(_gi_cairo_la_LINK) -rpath $(pygidir) $(_gi_cairo_la_OBJECTS) $(_gi_cairo_la_LIBADD) $(LIBS)
+ $(AM_V_CCLD)$(_gi_cairo_la_LINK) $(am__gi_cairo_la_rpath) $(_gi_cairo_la_OBJECTS) $(_gi_cairo_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -467,9 +475,11 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-boxed.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-callbacks.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-closure.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-foreign-gvariant.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-foreign.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-info.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-invoke.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-property.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-repository.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-struct.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-type.Plo@am__quote@
@@ -530,6 +540,14 @@ _gi_la-pygi-foreign.lo: pygi-foreign.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-foreign.lo `test -f 'pygi-foreign.c' || echo '$(srcdir)/'`pygi-foreign.c
+_gi_la-pygi-foreign-gvariant.lo: pygi-foreign-gvariant.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-foreign-gvariant.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-foreign-gvariant.Tpo -c -o _gi_la-pygi-foreign-gvariant.lo `test -f 'pygi-foreign-gvariant.c' || echo '$(srcdir)/'`pygi-foreign-gvariant.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-foreign-gvariant.Tpo $(DEPDIR)/_gi_la-pygi-foreign-gvariant.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-foreign-gvariant.c' object='_gi_la-pygi-foreign-gvariant.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-foreign-gvariant.lo `test -f 'pygi-foreign-gvariant.c' || echo '$(srcdir)/'`pygi-foreign-gvariant.c
+
_gi_la-pygi-struct.lo: pygi-struct.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-struct.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-struct.Tpo -c -o _gi_la-pygi-struct.lo `test -f 'pygi-struct.c' || echo '$(srcdir)/'`pygi-struct.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-struct.Tpo $(DEPDIR)/_gi_la-pygi-struct.Plo
@@ -578,6 +596,14 @@ _gi_la-pygi-callbacks.lo: pygi-callbacks.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-callbacks.lo `test -f 'pygi-callbacks.c' || echo '$(srcdir)/'`pygi-callbacks.c
+_gi_la-pygi-property.lo: pygi-property.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-property.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-property.Tpo -c -o _gi_la-pygi-property.lo `test -f 'pygi-property.c' || echo '$(srcdir)/'`pygi-property.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-property.Tpo $(DEPDIR)/_gi_la-pygi-property.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-property.c' object='_gi_la-pygi-property.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-property.lo `test -f 'pygi-property.c' || echo '$(srcdir)/'`pygi-property.c
+
_gi_la-gimodule.lo: gimodule.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-gimodule.lo -MD -MP -MF $(DEPDIR)/_gi_la-gimodule.Tpo -c -o _gi_la-gimodule.lo `test -f 'gimodule.c' || echo '$(srcdir)/'`gimodule.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-gimodule.Tpo $(DEPDIR)/_gi_la-gimodule.Plo
@@ -960,15 +986,13 @@ uninstall-am: uninstall-pygiLTLIBRARIES uninstall-pygiPYTHON
# This is to ensure we have a symlink to the .so in the
# build directory, which the Python interpreter can load
# directly without having to know how to parse .la files.
-_gi.so: _gi.la
- rm -f $@ && $(LN_S) .libs/$@ $@
-_gi_cairo.so: _gi_cairo.la
- rm -f $@ && $(LN_S) .libs/$@ $@
+.la.so:
+ test -L $@ || $(LN_S) .libs/$@ $@
-all-local: _gi.so _gi_cairo.so
-check-local: _gi.so _gi_cairo.so
+all-local: $(LTLIBRARIES:.la=.so)
+check-local: $(LTLIBRARIES:.la=.so)
clean-local:
- rm -f _gi.so _gi_cairo.so
+ rm -f $(LTLIBRARIES:.la=.so)
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/gi/gimodule.c b/gi/gimodule.c
index df0db7a..89caf4e 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -25,6 +25,7 @@
#include "pygi.h"
#include <pygobject.h>
+#include <pyglib-python-compat.h>
static PyObject *
_wrap_pyg_enum_add (PyObject *self,
@@ -195,12 +196,17 @@ _wrap_pyg_hook_up_vfunc_implementation (PyObject *self, PyObject *args)
field_info = g_struct_info_get_field (struct_info, i);
if (strcmp (g_base_info_get_name ( (GIBaseInfo*) field_info),
- g_base_info_get_name ( (GIBaseInfo*) vfunc_info)) != 0)
+ g_base_info_get_name ( (GIBaseInfo*) vfunc_info)) != 0) {
+ g_base_info_unref (field_info);
continue;
+ }
type_info = g_field_info_get_type (field_info);
- if (g_type_info_get_tag (type_info) != GI_TYPE_TAG_INTERFACE)
+ if (g_type_info_get_tag (type_info) != GI_TYPE_TAG_INTERFACE) {
+ g_base_info_unref (type_info);
+ g_base_info_unref (field_info);
continue;
+ }
interface_info = g_type_info_get_interface (type_info);
g_assert (g_base_info_get_type (interface_info) == GI_INFO_TYPE_CALLBACK);
@@ -229,32 +235,85 @@ _wrap_pyg_hook_up_vfunc_implementation (PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
-static PyMethodDef _pygi_functions[] = {
+static PyObject *
+_wrap_pyg_variant_new_tuple (PyObject *self, PyObject *args)
+{
+ PyObject *py_values;
+ GVariant **values = NULL;
+ GVariant *variant = NULL;
+ PyObject *py_variant = NULL;
+ PyObject *py_type;
+ gssize i;
+
+ if (!PyArg_ParseTuple (args, "O!:variant_new_tuple",
+ &PyTuple_Type, &py_values)) {
+ return NULL;
+ }
+
+ py_type = _pygi_type_import_by_name ("GLib", "Variant");
+
+ values = g_newa (GVariant*, PyTuple_Size (py_values));
+
+ for (i = 0; i < PyTuple_Size (py_values); i++) {
+ PyObject *value = PyTuple_GET_ITEM (py_values, i);
+
+ if (!PyObject_IsInstance (value, py_type)) {
+ PyErr_Format (PyExc_TypeError, "argument %d is not a GLib.Variant", i);
+ return NULL;
+ }
+
+ values[i] = (GVariant *) ( (PyGPointer *) value)->pointer;
+ }
+
+ variant = g_variant_new_tuple (values, PyTuple_Size (py_values));
+
+ py_variant = _pygi_struct_new ( (PyTypeObject *) py_type, variant, FALSE);
+
+ return py_variant;
+}
+
+static PyObject *
+_wrap_pyg_variant_type_from_string (PyObject *self, PyObject *args)
+{
+ char *type_string;
+ PyObject *py_type;
+ PyObject *py_variant = NULL;
+
+ if (!PyArg_ParseTuple (args, "s:variant_type_from_string",
+ &type_string)) {
+ return NULL;
+ }
+
+ py_type = _pygi_type_import_by_name ("GLib", "VariantType");
+
+ py_variant = _pygi_struct_new ( (PyTypeObject *) py_type, type_string, FALSE);
+
+ return py_variant;
+}
+
+static PyMethodDef _gi_functions[] = {
{ "enum_add", (PyCFunction) _wrap_pyg_enum_add, METH_VARARGS | METH_KEYWORDS },
{ "flags_add", (PyCFunction) _wrap_pyg_flags_add, METH_VARARGS | METH_KEYWORDS },
{ "set_object_has_new_constructor", (PyCFunction) _wrap_pyg_set_object_has_new_constructor, METH_VARARGS | METH_KEYWORDS },
{ "register_interface_info", (PyCFunction) _wrap_pyg_register_interface_info, METH_VARARGS },
{ "hook_up_vfunc_implementation", (PyCFunction) _wrap_pyg_hook_up_vfunc_implementation, METH_VARARGS },
+ { "variant_new_tuple", (PyCFunction) _wrap_pyg_variant_new_tuple, METH_VARARGS },
+ { "variant_type_from_string", (PyCFunction) _wrap_pyg_variant_type_from_string, METH_VARARGS },
{ 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_register_foreign_struct_real,
};
-PyMODINIT_FUNC
-init_gi (void)
+PYGLIB_MODULE_START(_gi, "_gi")
{
- PyObject *m;
PyObject *api;
- m = Py_InitModule ("_gi", _pygi_functions);
- if (m == NULL) {
- return;
- }
-
if (pygobject_init (-1, -1, -1) == NULL) {
return;
}
@@ -263,16 +322,16 @@ init_gi (void)
return;
}
- _pygi_repository_register_types (m);
- _pygi_info_register_types (m);
- _pygi_struct_register_types (m);
- _pygi_boxed_register_types (m);
+ _pygi_repository_register_types (module);
+ _pygi_info_register_types (module);
+ _pygi_struct_register_types (module);
+ _pygi_boxed_register_types (module);
_pygi_argument_init();
api = PyCObject_FromVoidPtr ( (void *) &CAPI, NULL);
if (api == NULL) {
return;
}
- PyModule_AddObject (m, "_API", api);
+ PyModule_AddObject (module, "_API", api);
}
-
+PYGLIB_MODULE_END
diff --git a/gi/importer.py b/gi/importer.py
index 6076692..1cb9b92 100644
--- a/gi/importer.py
+++ b/gi/importer.py
@@ -27,7 +27,7 @@ import sys
import gobject
from ._gi import Repository, RepositoryError
-from .module import DynamicModule, DynamicGObjectModule, ModuleProxy
+from .module import DynamicModule, DynamicGObjectModule
repository = Repository.get_default()
@@ -48,10 +48,10 @@ class DynamicImporter(object):
path, namespace = fullname.rsplit('.', 1)
if path != self.path:
return
- try:
- repository.require(namespace)
- except RepositoryError, e:
- logging.exception(e)
+
+ if not repository.enumerate_versions(namespace):
+ logging.error('Could not find any typelib for %s', namespace)
+ return None
else:
return self
@@ -69,18 +69,10 @@ class DynamicImporter(object):
dynamic_module = DynamicModule(namespace)
modules[namespace] = dynamic_module
- overrides_modules = __import__('gi.overrides', fromlist=[namespace])
- overrides_module = getattr(overrides_modules, namespace, None)
-
- if overrides_module is not None:
- module = ModuleProxy(fullname, namespace, dynamic_module, overrides_module)
- else:
- module = dynamic_module
-
- module.__file__ = '<%s>' % fullname
- module.__loader__ = self
+ dynamic_module.__file__ = '<%s>' % fullname
+ dynamic_module.__loader__ = self
- sys.modules[fullname] = module
+ sys.modules[fullname] = dynamic_module
- return module
+ return dynamic_module
diff --git a/gi/module.py b/gi/module.py
index e149986..819fcc6 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -64,6 +64,7 @@ def get_parent_for_object(object_info):
module = __import__('gi.repository.%s' % namespace, fromlist=[name])
return getattr(module, name)
+
def get_interfaces_for_object(object_info):
interfaces = []
for interface_info in object_info.get_interfaces():
@@ -75,17 +76,24 @@ def get_interfaces_for_object(object_info):
return interfaces
-class DynamicModule(object):
+class IntrospectionModule(object):
- def __init__(self, namespace):
+ def __init__(self, namespace, version=None):
+ repository.require(namespace, version)
self._namespace = namespace
+ self.version = version
self.__name__ = 'gi.repository.' + namespace
+ repository.require(self._namespace, self.version)
+
+ if self.version is None:
+ self.version = repository.get_version(self._namespace)
+
def __getattr__(self, name):
info = repository.find_by_name(self._namespace, name)
if not info:
raise AttributeError("%r object has no attribute %r" % (
- self.__class__.__name__, name))
+ self.__name__, name))
if isinstance(info, EnumInfo):
g_type = info.get_g_type()
@@ -133,7 +141,7 @@ class DynamicModule(object):
elif g_type.is_a(gobject.TYPE_POINTER) or g_type == gobject.TYPE_NONE:
bases = (Struct,)
else:
- raise TypeError, "unable to create a wrapper for %s.%s" % (info.get_namespace(), info.get_name())
+ raise TypeError("unable to create a wrapper for %s.%s" % (info.get_namespace(), info.get_name()))
metaclass = StructMeta
else:
raise NotImplementedError(info)
@@ -162,10 +170,10 @@ class DynamicModule(object):
def __repr__(self):
path = repository.get_typelib_path(self._namespace)
- return "<DynamicModule %r from %r>" % (self._namespace, path)
+ return "<IntrospectionModule %r from %r>" % (self._namespace, path)
-class DynamicGObjectModule(DynamicModule):
+class DynamicGObjectModule(IntrospectionModule):
"""Wrapper for the GObject module
This class allows us to access both the static PyGObject module and the GI GObject module
@@ -182,12 +190,11 @@ class DynamicGObjectModule(DynamicModule):
"""
def __init__(self):
- self._namespace = 'GObject'
- self._module = gobject
+ IntrospectionModule.__init__(self, namespace='GObject')
def __getattr__(self, name):
# first see if this attr is in the gobject module
- attr = getattr(self._module, name, None)
+ attr = getattr(gobject, name, None)
# if not in module assume request for an attr exported through GI
if attr is None:
@@ -195,23 +202,34 @@ class DynamicGObjectModule(DynamicModule):
return attr
-class ModuleProxy(object):
-
- def __init__(self, name, namespace, dynamic_module, overrides_module):
- self.__name__ = name
+class DynamicModule(object):
+ def __init__(self, namespace):
self._namespace = namespace
- self._dynamic_module = dynamic_module
- self._overrides_module = overrides_module
+ self.introspection_module = None
+ self._version = None
+ self._overrides_module = None
+
+ def require_version(self, version):
+ if self.introspection_module is not None and \
+ self.introspection_module.version != version:
+ raise RuntimeError('Module has been already loaded ')
+ self._version = version
+
+ def _import(self):
+ self.introspection_module = IntrospectionModule(self._namespace,
+ self._version)
+
+ overrides_modules = __import__('gi.overrides', fromlist=[self._namespace])
+ self._overrides_module = getattr(overrides_modules, self._namespace, None)
def __getattr__(self, name):
- override_exports = getattr(self._overrides_module, '__all__', ())
- if (name in override_exports):
- attribute = getattr(self._overrides_module, name, None)
- else:
- attribute = getattr(self._dynamic_module, name)
- return attribute
+ if self.introspection_module is None:
+ self._import()
- def __str__(self):
- return "<ModuleProxy %r>" % self.__name__
+ if self._overrides_module is not None:
+ override_exports = getattr(self._overrides_module, '__all__', ())
+ if name in override_exports:
+ return getattr(self._overrides_module, name, None)
+ return getattr(self.introspection_module, name)
diff --git a/gi/overrides/GIMarshallingTests.py b/gi/overrides/GIMarshallingTests.py
index 768efd7..ee01495 100644
--- a/gi/overrides/GIMarshallingTests.py
+++ b/gi/overrides/GIMarshallingTests.py
@@ -21,7 +21,7 @@
from ..types import override
from ..importer import modules
-GIMarshallingTests = modules['GIMarshallingTests']
+GIMarshallingTests = modules['GIMarshallingTests'].introspection_module
__all__ = []
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
new file mode 100644
index 0000000..78d8c35
--- /dev/null
+++ b/gi/overrides/GLib.py
@@ -0,0 +1,165 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2010 Tomeu Vizoso <tomeu.vizoso@collabora.co.uk>
+#
+# 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
+
+from ..importer import modules
+from .._gi import variant_new_tuple, variant_type_from_string
+
+GLib = modules['GLib'].introspection_module
+
+__all__ = []
+
+class _VariantCreator(object):
+
+ _LEAF_CONSTRUCTORS = {
+ 'b': GLib.Variant.new_boolean,
+ 'y': GLib.Variant.new_byte,
+ 'n': GLib.Variant.new_int16,
+ 'q': GLib.Variant.new_uint16,
+ 'i': GLib.Variant.new_int32,
+ 'u': GLib.Variant.new_uint32,
+ 'x': GLib.Variant.new_int64,
+ 't': GLib.Variant.new_uint64,
+ 'h': GLib.Variant.new_handle,
+ 'd': GLib.Variant.new_double,
+ 's': GLib.Variant.new_string,
+ 'o': GLib.Variant.new_object_path,
+ 'g': GLib.Variant.new_signature,
+ 'v': GLib.Variant.new_variant,
+ }
+
+ def __init__(self, format_string, args):
+ self._format_string = format_string
+ self._args = args
+
+ def create(self):
+ if self._format_string_is_leaf():
+ return self._new_variant_leaf()
+
+ format_char = self._pop_format_char()
+ arg = self._pop_arg()
+
+ if format_char == 'm':
+ raise NotImplementedError()
+ else:
+ builder = GLib.VariantBuilder()
+ if format_char == '(':
+ builder.init(variant_type_from_string('r'))
+ elif format_char == '{':
+ builder.init(variant_type_from_string('{?*}'))
+ else:
+ raise NotImplementedError()
+ format_char = self._pop_format_char()
+ while format_char not in [')', '}']:
+ builder.add_value(Variant(format_char, arg))
+ format_char = self._pop_format_char()
+ if self._args:
+ arg = self._pop_arg()
+ return builder.end()
+
+ def _format_string_is_leaf(self):
+ format_char = self._format_string[0]
+ return not format_char in ['m', '(', '{']
+
+ def _format_string_is_nnp(self):
+ format_char = self._format_string[0]
+ return format_char in ['a', 's', 'o', 'g', '^', '@', '*', '?', 'r',
+ 'v', '&']
+
+ def _new_variant_leaf(self):
+ if self._format_string_is_nnp():
+ return self._new_variant_nnp()
+
+ format_char = self._pop_format_char()
+ arg = self._pop_arg()
+
+ return _VariantCreator._LEAF_CONSTRUCTORS[format_char](arg)
+
+ def _new_variant_nnp(self):
+ format_char = self._pop_format_char()
+ arg = self._pop_arg()
+
+ if format_char == '&':
+ format_char = self._pop_format_char()
+
+ if format_char == 'a':
+ builder = GLib.VariantBuilder()
+ builder.init(variant_type_from_string('a*'))
+
+ element_format_string = self._pop_leaf_format_string()
+
+ if isinstance(arg, dict):
+ for element in arg.items():
+ value = Variant(element_format_string, *element)
+ builder.add_value(value)
+ else:
+ for element in arg:
+ value = Variant(element_format_string, element)
+ builder.add_value(value)
+ return builder.end()
+ elif format_char == '^':
+ raise NotImplementedError()
+ elif format_char == '@':
+ raise NotImplementedError()
+ elif format_char == '*':
+ raise NotImplementedError()
+ elif format_char == 'r':
+ raise NotImplementedError()
+ elif format_char == '?':
+ raise NotImplementedError()
+ else:
+ return _VariantCreator._LEAF_CONSTRUCTORS[format_char](arg)
+
+ def _pop_format_char(self):
+ format_char = self._format_string[0]
+ self._format_string = self._format_string[1:]
+ return format_char
+
+ def _pop_leaf_format_string(self):
+ # FIXME: This will break when the leaf is inside a tuple or dict entry
+ format_string = self._format_string
+ self._format_string = ''
+ return format_string
+
+ def _pop_arg(self):
+ arg = self._args[0]
+ self._args = self._args[1:]
+ return arg
+
+class Variant(GLib.Variant):
+ def __new__(cls, format_string, *args):
+ creator = _VariantCreator(format_string, args)
+ return creator.create()
+
+ def __repr__(self):
+ return '<GLib.Variant(%s)>' % getattr(self, 'print')(True)
+
+@classmethod
+def new_tuple(cls, *elements):
+ return variant_new_tuple(elements)
+
+def get_string(self):
+ value, length = GLib.Variant.get_string(self)
+ return value
+
+setattr(Variant, 'new_tuple', new_tuple)
+setattr(Variant, 'get_string', get_string)
+
+__all__.append('Variant')
+
diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py
index 4eaff08..23a9d8e 100644
--- a/gi/overrides/Gdk.py
+++ b/gi/overrides/Gdk.py
@@ -22,7 +22,7 @@
from ..types import override
from ..importer import modules
-Gdk = modules['Gdk']
+Gdk = modules['Gdk'].introspection_module
__all__ = []
@@ -43,6 +43,25 @@ class Color(Gdk.Color):
Color = override(Color)
__all__.append('Color')
+if Gdk.version == '2.0':
+ class Rectangle(Gdk.Rectangle):
+
+ def __init__(self, x, y, width, height):
+ Gdk.Rectangle.__init__(self)
+ self.x = x
+ self.y = y
+ self.width = width
+ self.height = height
+
+ def __new__(cls, *args, **kwargs):
+ return Gdk.Rectangle.__new__(cls)
+
+ def __repr__(self):
+ return '<Gdk.Rectangle(x=%d, y=%d, width=%d, height=%d)>' % (self.x, self.y, self.height, self.width)
+
+ Rectangle = override(Rectangle)
+ __all__.append('Rectangle')
+
class Drawable(Gdk.Drawable):
def cairo_create(self):
return Gdk.cairo_create(self)
@@ -50,6 +69,54 @@ class Drawable(Gdk.Drawable):
Drawable = override(Drawable)
__all__.append('Drawable')
+class Event(Gdk.Event):
+ _UNION_MEMBERS = {
+ Gdk.EventType.DELETE: 'any',
+ Gdk.EventType.DESTROY: 'any',
+ Gdk.EventType.EXPOSE: 'expose',
+ Gdk.EventType.MOTION_NOTIFY: 'motion',
+ Gdk.EventType.BUTTON_PRESS: 'button',
+ #Gdk.EventType.2BUTTON_PRESS: 'button',
+ #Gdk.EventType.3BUTTON_PRESS: 'button',
+ Gdk.EventType.BUTTON_RELEASE: 'button',
+ Gdk.EventType.KEY_PRESS: 'key',
+ Gdk.EventType.KEY_RELEASE: 'key',
+ Gdk.EventType.ENTER_NOTIFY: 'crossing',
+ Gdk.EventType.LEAVE_NOTIFY: 'crossing',
+ Gdk.EventType.FOCUS_CHANGE: 'focus_change',
+ Gdk.EventType.CONFIGURE: 'configure',
+ Gdk.EventType.MAP: 'any',
+ Gdk.EventType.UNMAP: 'any',
+ Gdk.EventType.PROPERTY_NOTIFY: 'property',
+ Gdk.EventType.SELECTION_CLEAR: 'selection',
+ Gdk.EventType.SELECTION_REQUEST: 'selection',
+ Gdk.EventType.SELECTION_NOTIFY: 'selection',
+ Gdk.EventType.PROXIMITY_IN: 'proximity',
+ Gdk.EventType.PROXIMITY_OUT: 'proximity',
+ Gdk.EventType.DRAG_ENTER: 'dnd',
+ Gdk.EventType.DRAG_LEAVE: 'dnd',
+ Gdk.EventType.DRAG_MOTION: 'dnd',
+ Gdk.EventType.DRAG_STATUS: 'dnd',
+ Gdk.EventType.DROP_START: 'dnd',
+ Gdk.EventType.DROP_FINISHED: 'dnd',
+ Gdk.EventType.CLIENT_EVENT: 'client',
+ Gdk.EventType.VISIBILITY_NOTIFY: 'visibility',
+ Gdk.EventType.NO_EXPOSE: 'no_expose'
+ }
+
+ def __new__(cls, *args, **kwargs):
+ return Gdk.Event.__new__(cls)
+
+ def __getattr__(self, name):
+ real_event = getattr(self, '_UNION_MEMBERS').get(self.type)
+ if real_event:
+ return getattr(getattr(self, real_event), name)
+ else:
+ return getattr(self, name)
+
+Event = override(Event)
+__all__.append('Event')
+
import sys
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index 38a90b3..1f6901c 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -19,13 +19,21 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
+import sys
import gobject
from gi.repository import Gdk
from gi.repository import GObject
from ..types import override
from ..importer import modules
-Gtk = modules['Gtk']
+if sys.version_info >= (3, 0):
+ _basestring = str
+ _callable = lambda c: hasattr(c, '__call__')
+else:
+ _basestring = basestring
+ _callable = callable
+
+Gtk = modules['Gtk'].introspection_module
__all__ = []
class ActionGroup(Gtk.ActionGroup):
@@ -184,7 +192,7 @@ __all__.append('ActionGroup')
class UIManager(Gtk.UIManager):
def add_ui_from_string(self, buffer):
- if not isinstance(buffer, basestring):
+ if not isinstance(buffer, _basestring):
raise TypeError('buffer must be a string')
length = len(buffer)
@@ -207,7 +215,7 @@ class Builder(Gtk.Builder):
if handler is None:
raise AttributeError('Handler %s not found' % handler_name)
- if not callable(handler):
+ if not _callable(handler):
raise TypeError('Handler %s is not a method or function' % handler_name)
after = flags or GObject.ConnectFlags.AFTER
@@ -226,7 +234,7 @@ class Builder(Gtk.Builder):
obj_or_map);
def add_from_string(self, buffer):
- if not isinstance(buffer, basestring):
+ if not isinstance(buffer, _basestring):
raise TypeError('buffer must be a string')
length = len(buffer)
@@ -234,7 +242,7 @@ class Builder(Gtk.Builder):
return Gtk.Builder.add_from_string(self, buffer, length)
def add_objects_from_string(self, buffer, object_ids):
- if not isinstance(buffer, basestring):
+ if not isinstance(buffer, _basestring):
raise TypeError('buffer must be a string')
length = len(buffer)
@@ -256,8 +264,14 @@ class Dialog(Gtk.Dialog):
self.set_modal(True)
if flags & Gtk.DialogFlags.DESTROY_WITH_PARENT:
self.set_destroy_with_parent(True)
- if flags & Gtk.DialogFlags.NO_SEPARATOR:
- self.set_has_separator(False)
+
+ # NO_SEPARATOR has been removed from Gtk 3
+ try:
+ if flags & Gtk.DialogFlags.NO_SEPARATOR:
+ self.set_has_separator(False)
+ except AttributeError:
+ pass
+
if buttons:
self.add_buttons(*buttons)
@@ -324,14 +338,14 @@ class TextBuffer(Gtk.TextBuffer):
return tag
def insert(self, iter, text):
- if not isinstance(text , basestring):
+ if not isinstance(text , _basestring):
raise TypeError('text must be a string, not %s' % type(text))
length = len(text)
Gtk.TextBuffer.insert(self, iter, text, length)
def insert_at_cursor(self, text):
- if not isinstance(text , basestring):
+ if not isinstance(text , _basestring):
raise TypeError('text must be a string, not %s' % type(text))
length = len(text)
@@ -382,7 +396,7 @@ class TreeStore(Gtk.TreeStore, TreeModel):
if len(row) != n_columns:
raise ValueError('row sequence has the incorrect number of elements')
- for i in xrange(n_columns):
+ for i in range(n_columns):
if row[i] is not None:
self.set_value(treeiter, i, row[i])
@@ -399,12 +413,25 @@ class TreeViewColumn(Gtk.TreeViewColumn):
if cell_renderer:
self.pack_start(cell_renderer, True)
- for (name, value) in attributes.iteritems():
+ for (name, value) in attributes.items():
self.add_attribute(cell_renderer, name, value)
TreeViewColumn = override(TreeViewColumn)
__all__.append('TreeViewColumn')
+class Button(Gtk.Button):
+ def __init__(self, label=None, stock=None, use_underline=False):
+ if stock:
+ label = stock
+ use_stock = True
+ use_underline = True
+ else:
+ use_stock = False
+ Gtk.Button.__init__(self, label=label, use_stock=use_stock,
+ use_underline=use_underline)
+Button = override(Button)
+__all__.append('Button')
+
import sys
initialized, argv = Gtk.init_check(sys.argv)
diff --git a/gi/overrides/Makefile.am b/gi/overrides/Makefile.am
index 62f6457..b36c7a5 100644
--- a/gi/overrides/Makefile.am
+++ b/gi/overrides/Makefile.am
@@ -4,6 +4,7 @@ pkgpyexecdir = $(pyexecdir)/gtk-2.0/gi
pygioverridesdir = $(pkgpyexecdir)/overrides
pygioverrides_PYTHON = \
+ GLib.py \
Gtk.py \
Gdk.py \
GIMarshallingTests.py \
diff --git a/gi/overrides/Makefile.in b/gi/overrides/Makefile.in
index b0a8c01..630735c 100644
--- a/gi/overrides/Makefile.in
+++ b/gi/overrides/Makefile.in
@@ -115,6 +115,7 @@ GIOUNIX_LIBS = @GIOUNIX_LIBS@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
GI_CFLAGS = @GI_CFLAGS@
+GI_DATADIR = @GI_DATADIR@
GI_LIBS = @GI_LIBS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
@@ -237,6 +238,7 @@ top_srcdir = @top_srcdir@
PLATFORM_VERSION = 2.0
pygioverridesdir = $(pkgpyexecdir)/overrides
pygioverrides_PYTHON = \
+ GLib.py \
Gtk.py \
Gdk.py \
GIMarshallingTests.py \
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 9ace5d2..e3dd8c3 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
*
- * pygi-argument.c: GArgument - PyObject conversion functions.
+ * pygi-argument.c: GIArgument - PyObject conversion functions.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,7 @@
#include <datetime.h>
#include <pygobject.h>
-
+#include <pyglib-python-compat.h>
static void
_pygi_g_type_tag_py_bounds (GITypeTag type_tag,
@@ -37,29 +37,29 @@ _pygi_g_type_tag_py_bounds (GITypeTag type_tag,
{
switch (type_tag) {
case GI_TYPE_TAG_INT8:
- *lower = PyInt_FromLong (-128);
- *upper = PyInt_FromLong (127);
+ *lower = PYGLIB_PyLong_FromLong (-128);
+ *upper = PYGLIB_PyLong_FromLong (127);
break;
case GI_TYPE_TAG_UINT8:
- *upper = PyInt_FromLong (255);
- *lower = PyInt_FromLong (0);
+ *upper = PYGLIB_PyLong_FromLong (255);
+ *lower = PYGLIB_PyLong_FromLong (0);
break;
case GI_TYPE_TAG_INT16:
- *lower = PyInt_FromLong (-32768);
- *upper = PyInt_FromLong (32767);
+ *lower = PYGLIB_PyLong_FromLong (-32768);
+ *upper = PYGLIB_PyLong_FromLong (32767);
break;
case GI_TYPE_TAG_UINT16:
- *upper = PyInt_FromLong (65535);
- *lower = PyInt_FromLong (0);
+ *upper = PYGLIB_PyLong_FromLong (65535);
+ *lower = PYGLIB_PyLong_FromLong (0);
break;
case GI_TYPE_TAG_INT32:
- *lower = PyInt_FromLong (G_MININT32);
- *upper = PyInt_FromLong (G_MAXINT32);
+ *lower = PYGLIB_PyLong_FromLong (G_MININT32);
+ *upper = PYGLIB_PyLong_FromLong (G_MAXINT32);
break;
case GI_TYPE_TAG_UINT32:
/* Note: On 32-bit archs, this number doesn't fit in a long. */
*upper = PyLong_FromLongLong (G_MAXUINT32);
- *lower = PyInt_FromLong (0);
+ *lower = PYGLIB_PyLong_FromLong (0);
break;
case GI_TYPE_TAG_INT64:
/* Note: On 32-bit archs, these numbers don't fit in a long. */
@@ -68,7 +68,7 @@ _pygi_g_type_tag_py_bounds (GITypeTag type_tag,
break;
case GI_TYPE_TAG_UINT64:
*upper = PyLong_FromUnsignedLongLong (G_MAXUINT64);
- *lower = PyInt_FromLong (0);
+ *lower = PYGLIB_PyLong_FromLong (0);
break;
case GI_TYPE_TAG_FLOAT:
*upper = PyFloat_FromDouble (G_MAXFLOAT);
@@ -161,6 +161,101 @@ _pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
}
gint
+_pygi_g_type_interface_check_object (GIBaseInfo *info,
+ PyObject *object)
+{
+ gint retval = 1;
+ GIInfoType info_type;
+
+ info_type = g_base_info_get_type (info);
+ switch (info_type) {
+ case GI_INFO_TYPE_CALLBACK:
+ if (!PyCallable_Check (object)) {
+ PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ }
+ break;
+ case GI_INFO_TYPE_ENUM:
+ retval = 0;
+ if (PyNumber_Check (object)) {
+ PyObject *number = PYGLIB_PyNumber_Long (object);
+ if (number == NULL)
+ PyErr_Clear();
+ else {
+ glong value = PYGLIB_PyLong_AsLong (number);
+ int i;
+ for (i = 0; i < g_enum_info_get_n_values (info); i++) {
+ GIValueInfo *value_info = g_enum_info_get_value (info, i);
+ glong enum_value = g_value_info_get_value (value_info);
+ if (value == enum_value) {
+ retval = 1;
+ break;
+ }
+ }
+ }
+ }
+ if (retval < 1)
+ retval = _pygi_g_registered_type_info_check_object (
+ (GIRegisteredTypeInfo *) info, TRUE, object);
+ break;
+ case GI_INFO_TYPE_FLAGS:
+ if (PyNumber_Check (object)) {
+ /* Accept 0 as a valid flag value */
+ PyObject *number = PYGLIB_PyNumber_Long (object);
+ if (number == NULL)
+ PyErr_Clear();
+ else {
+ long value = PYGLIB_PyLong_AsLong (number);
+ if (value == 0)
+ break;
+ else if (value == -1)
+ PyErr_Clear();
+ }
+ }
+ retval = _pygi_g_registered_type_info_check_object (
+ (GIRegisteredTypeInfo *) info, TRUE, object);
+ break;
+ case GI_INFO_TYPE_STRUCT:
+ {
+ GType type;
+
+ /* Handle special cases. */
+ type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
+ if (g_type_is_a (type, G_TYPE_VALUE)) {
+ GType object_type;
+ object_type = pyg_type_from_object ( (PyObject *) object->ob_type);
+ if (object_type == G_TYPE_INVALID) {
+ PyErr_Format (PyExc_TypeError, "Must be of a known GType, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ }
+ break;
+ } else if (g_type_is_a (type, G_TYPE_CLOSURE)) {
+ if (!PyCallable_Check (object)) {
+ PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ }
+ break;
+ }
+
+ /* Fallback. */
+ }
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_INTERFACE:
+ case GI_INFO_TYPE_OBJECT:
+ case GI_INFO_TYPE_UNION:
+ retval = _pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) info, TRUE, object);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ return retval;
+}
+
+gint
_pygi_g_type_info_check_object (GITypeInfo *type_info,
PyObject *object,
gboolean allow_none)
@@ -204,7 +299,7 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
if (type_tag == GI_TYPE_TAG_FLOAT || type_tag == GI_TYPE_TAG_DOUBLE) {
number = PyNumber_Float (object);
} else {
- number = PyNumber_Int (object);
+ number = PYGLIB_PyNumber_Long (object);
}
_pygi_g_type_tag_py_bounds (type_tag, &lower, &upper);
@@ -215,8 +310,8 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
}
/* Check bounds */
- if (PyObject_Compare (lower, number) > 0
- || PyObject_Compare (upper, number) < 0) {
+ if (PyObject_RichCompareBool (lower, number, Py_GT)
+ || PyObject_RichCompareBool (upper, number, Py_LT)) {
PyObject *lower_str;
PyObject *upper_str;
@@ -232,10 +327,30 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
goto check_number_error_release;
}
+#if PY_VERSION_HEX < 0x03000000
PyErr_Format (PyExc_ValueError, "Must range from %s to %s",
PyString_AS_STRING (lower_str),
PyString_AS_STRING (upper_str));
+#else
+ {
+ PyObject *lower_pybytes_obj = PyUnicode_AsUTF8String (lower_str);
+ if (!lower_pybytes_obj)
+ goto utf8_fail;
+
+ PyObject *upper_pybytes_obj = PyUnicode_AsUTF8String (upper_str);
+ if (!upper_pybytes_obj) {
+ Py_DECREF(lower_pybytes_obj);
+ goto utf8_fail;
+ }
+ PyErr_Format (PyExc_ValueError, "Must range from %s to %s",
+ PyBytes_AsString (lower_pybytes_obj),
+ PyBytes_AsString (upper_pybytes_obj));
+ Py_DECREF (lower_pybytes_obj);
+ Py_DECREF (upper_pybytes_obj);
+ }
+utf8_fail:
+#endif
retval = 0;
check_number_error_release:
@@ -251,15 +366,7 @@ check_number_release:
}
case GI_TYPE_TAG_GTYPE:
{
- gint is_instance;
-
- is_instance = PyObject_IsInstance (object, (PyObject *) &PyGTypeWrapper_Type);
- if (is_instance < 0) {
- retval = -1;
- break;
- }
-
- if (!is_instance && (!PyType_Check (object) || pyg_type_from_object (object) == 0)) {
+ if (pyg_type_from_object (object) == 0) {
PyErr_Format (PyExc_TypeError, "Must be gobject.GType, not %s",
object->ob_type->tp_name);
retval = 0;
@@ -268,7 +375,7 @@ check_number_release:
}
case GI_TYPE_TAG_UTF8:
case GI_TYPE_TAG_FILENAME:
- if (!PyString_Check (object)) {
+ if (!PYGLIB_PyUnicode_Check (object)) {
PyErr_Format (PyExc_TypeError, "Must be string, not %s",
object->ob_type->tp_name);
retval = 0;
@@ -334,77 +441,11 @@ check_number_release:
case GI_TYPE_TAG_INTERFACE:
{
GIBaseInfo *info;
- GIInfoType info_type;
info = g_type_info_get_interface (type_info);
g_assert (info != NULL);
- info_type = g_base_info_get_type (info);
-
- switch (info_type) {
- case GI_INFO_TYPE_CALLBACK:
- if (!PyCallable_Check (object)) {
- PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
- object->ob_type->tp_name);
- retval = 0;
- }
- break;
- case GI_INFO_TYPE_ENUM:
- retval = _pygi_g_registered_type_info_check_object (
- (GIRegisteredTypeInfo *) info, TRUE, object);
- break;
- case GI_INFO_TYPE_FLAGS:
- if (PyNumber_Check (object)) {
- /* Accept 0 as a valid flag value */
- PyObject *number = PyNumber_Int (object);
- if (number == NULL)
- PyErr_Clear();
- else {
- long value = PyInt_AsLong (number);
- if (value == 0)
- break;
- else if (value == -1)
- PyErr_Clear();
- }
- }
- retval = _pygi_g_registered_type_info_check_object (
- (GIRegisteredTypeInfo *) info, TRUE, object);
- break;
- case GI_INFO_TYPE_STRUCT:
- {
- GType type;
-
- /* Handle special cases. */
- type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
- if (g_type_is_a (type, G_TYPE_VALUE)) {
- GType object_type;
- object_type = pyg_type_from_object ( (PyObject *) object->ob_type);
- if (object_type == G_TYPE_INVALID) {
- PyErr_Format (PyExc_TypeError, "Must be of a known GType, not %s",
- object->ob_type->tp_name);
- retval = 0;
- }
- break;
- } else if (g_type_is_a (type, G_TYPE_CLOSURE)) {
- if (!PyCallable_Check (object)) {
- PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
- object->ob_type->tp_name);
- retval = 0;
- }
- break;
- }
-
- /* Fallback. */
- }
- case GI_INFO_TYPE_BOXED:
- case GI_INFO_TYPE_INTERFACE:
- case GI_INFO_TYPE_OBJECT:
- case GI_INFO_TYPE_UNION:
- retval = _pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) info, TRUE, object);
- break;
- default:
- g_assert_not_reached();
- }
+ retval = _pygi_g_type_interface_check_object(info, object);
g_base_info_unref (info);
break;
@@ -466,7 +507,8 @@ check_number_release:
GITypeInfo *value_type_info;
Py_ssize_t i;
- if (!PyMapping_Check (object)) {
+ keys = PyMapping_Keys (object);
+ if (keys == NULL) {
PyErr_Format (PyExc_TypeError, "Must be mapping, not %s",
object->ob_type->tp_name);
retval = 0;
@@ -475,12 +517,7 @@ check_number_release:
length = PyMapping_Length (object);
if (length < 0) {
- retval = -1;
- break;
- }
-
- keys = PyMapping_Keys (object);
- if (keys == NULL) {
+ Py_DECREF (keys);
retval = -1;
break;
}
@@ -540,8 +577,8 @@ check_number_release:
}
GArray *
-_pygi_argument_to_array (GArgument *arg,
- GArgument *args[],
+_pygi_argument_to_array (GIArgument *arg,
+ GIArgument *args[],
GITypeInfo *type_info,
gboolean is_method)
{
@@ -572,12 +609,6 @@ _pygi_argument_to_array (GArgument *arg,
length_arg_pos = g_type_info_get_array_length (type_info);
g_assert (length_arg_pos >= 0);
- if (is_method) {
- length_arg_pos--;
- }
-
- g_assert (length_arg_pos >= 0);
-
/* FIXME: Take into account the type of the argument. */
length = args[length_arg_pos]->v_int;
}
@@ -593,15 +624,15 @@ _pygi_argument_to_array (GArgument *arg,
return g_array;
}
-GArgument
+GIArgument
_pygi_argument_from_object (PyObject *object,
GITypeInfo *type_info,
GITransfer transfer)
{
- GArgument arg;
+ GIArgument arg;
GITypeTag type_tag;
- memset(&arg, 0, sizeof(GArgument));
+ memset(&arg, 0, sizeof(GIArgument));
type_tag = g_type_info_get_tag (type_info);
switch (type_tag) {
@@ -622,12 +653,12 @@ _pygi_argument_from_object (PyObject *object,
{
PyObject *int_;
- int_ = PyNumber_Int (object);
+ int_ = PYGLIB_PyNumber_Long (object);
if (int_ == NULL) {
break;
}
- arg.v_long = PyInt_AsLong (int_);
+ arg.v_long = PYGLIB_PyLong_AsLong (int_);
Py_DECREF (int_);
@@ -639,16 +670,18 @@ _pygi_argument_from_object (PyObject *object,
PyObject *number;
guint64 value;
- number = PyNumber_Int (object);
+ number = PYGLIB_PyNumber_Long (object);
if (number == NULL) {
break;
}
+#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check (number)) {
value = PyInt_AS_LONG (number);
- } else {
+ } else
+#endif
+ if (PyLong_Check (number))
value = PyLong_AsUnsignedLongLong (number);
- }
arg.v_uint64 = value;
@@ -661,16 +694,18 @@ _pygi_argument_from_object (PyObject *object,
PyObject *number;
gint64 value;
- number = PyNumber_Int (object);
+ number = PYGLIB_PyNumber_Long (object);
if (number == NULL) {
break;
}
+#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check (number)) {
value = PyInt_AS_LONG (number);
- } else {
+ } else
+#endif
+ if (PyLong_Check (number))
value = PyLong_AsLongLong (number);
- }
arg.v_int64 = value;
@@ -714,30 +749,53 @@ _pygi_argument_from_object (PyObject *object,
}
case GI_TYPE_TAG_UTF8:
{
- const gchar *string;
+ gchar *string;
if (object == Py_None) {
arg.v_string = NULL;
break;
}
+#if PY_VERSION_HEX < 0x03000000
+ string = g_strdup(PyString_AsString (object));
+#else
+ {
+ PyObject *pybytes_obj = PyUnicode_AsUTF8String (object);
+ if (!pybytes_obj)
+ break;
- string = PyString_AsString (object);
+ string = g_strdup(PyBytes_AsString (pybytes_obj));
+ Py_DECREF (pybytes_obj);
+ }
+#endif
+ arg.v_string = string;
- /* Don't need to check for errors, since g_strdup is NULL-proof. */
- arg.v_string = g_strdup (string);
break;
}
case GI_TYPE_TAG_FILENAME:
{
GError *error = NULL;
- const gchar *string;
+ gchar *string;
+
+#if PY_VERSION_HEX < 0x03000000
+ string = g_strdup(PyString_AsString (object));
+#else
+ {
+ PyObject *pybytes_obj = PyUnicode_AsUTF8String (object);
+ if (!pybytes_obj)
+ break;
+
+ string = g_strdup(PyBytes_AsString (pybytes_obj));
+ Py_DECREF (pybytes_obj);
+ }
+#endif
- string = PyString_AsString (object);
if (string == NULL) {
break;
}
arg.v_string = g_filename_from_utf8 (string, -1, NULL, NULL, &error);
+ g_free(string);
+
if (arg.v_string == NULL) {
PyErr_SetString (PyExc_Exception, error->message);
/* TODO: Convert the error to an exception. */
@@ -781,7 +839,7 @@ _pygi_argument_from_object (PyObject *object,
for (i = 0; i < length; i++) {
PyObject *py_item;
- GArgument item;
+ GIArgument item;
py_item = PySequence_GetItem (object, i);
if (py_item == NULL) {
@@ -801,7 +859,7 @@ _pygi_argument_from_object (PyObject *object,
array_item_error:
/* Free everything we have converted so far. */
- _pygi_argument_release ( (GArgument *) &array, type_info,
+ _pygi_argument_release ( (GIArgument *) &array, type_info,
GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
array = NULL;
@@ -900,12 +958,12 @@ array_item_error:
{
PyObject *int_;
- int_ = PyNumber_Int (object);
+ int_ = PYGLIB_PyNumber_Long (object);
if (int_ == NULL) {
break;
}
- arg.v_long = PyInt_AsLong (int_);
+ arg.v_long = PYGLIB_PyLong_AsLong (int_);
Py_DECREF (int_);
@@ -956,7 +1014,7 @@ array_item_error:
for (i = length - 1; i >= 0; i--) {
PyObject *py_item;
- GArgument item;
+ GIArgument item;
py_item = PySequence_GetItem (object, i);
if (py_item == NULL) {
@@ -981,7 +1039,7 @@ array_item_error:
list_item_error:
/* Free everything we have converted so far. */
- _pygi_argument_release ( (GArgument *) &list, type_info,
+ _pygi_argument_release ( (GIArgument *) &list, type_info,
GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
list = NULL;
@@ -1061,8 +1119,8 @@ list_item_error:
for (i = 0; i < length; i++) {
PyObject *py_key;
PyObject *py_value;
- GArgument key;
- GArgument value;
+ GIArgument key;
+ GIArgument value;
py_key = PyList_GET_ITEM (keys, i);
py_value = PyList_GET_ITEM (values, i);
@@ -1083,7 +1141,7 @@ list_item_error:
hash_table_item_error:
/* Free everything we have converted so far. */
- _pygi_argument_release ( (GArgument *) &hash_table, type_info,
+ _pygi_argument_release ( (GIArgument *) &hash_table, type_info,
GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
hash_table = NULL;
@@ -1110,7 +1168,7 @@ hash_table_release:
}
PyObject *
-_pygi_argument_to_object (GArgument *arg,
+_pygi_argument_to_object (GIArgument *arg,
GITypeInfo *type_info,
GITransfer transfer)
{
@@ -1135,27 +1193,27 @@ _pygi_argument_to_object (GArgument *arg,
}
case GI_TYPE_TAG_INT8:
{
- object = PyInt_FromLong (arg->v_int8);
+ object = PYGLIB_PyLong_FromLong (arg->v_int8);
break;
}
case GI_TYPE_TAG_UINT8:
{
- object = PyInt_FromLong (arg->v_uint8);
+ object = PYGLIB_PyLong_FromLong (arg->v_uint8);
break;
}
case GI_TYPE_TAG_INT16:
{
- object = PyInt_FromLong (arg->v_int16);
+ object = PYGLIB_PyLong_FromLong (arg->v_int16);
break;
}
case GI_TYPE_TAG_UINT16:
{
- object = PyInt_FromLong (arg->v_uint16);
+ object = PYGLIB_PyLong_FromLong (arg->v_uint16);
break;
}
case GI_TYPE_TAG_INT32:
{
- object = PyInt_FromLong (arg->v_int32);
+ object = PYGLIB_PyLong_FromLong (arg->v_int32);
break;
}
case GI_TYPE_TAG_UINT32:
@@ -1195,7 +1253,7 @@ _pygi_argument_to_object (GArgument *arg,
break;
}
- object = PyString_FromString (arg->v_string);
+ object = PYGLIB_PyUnicode_FromString (arg->v_string);
break;
case GI_TYPE_TAG_FILENAME:
{
@@ -1215,7 +1273,7 @@ _pygi_argument_to_object (GArgument *arg,
break;
}
- object = PyString_FromString (string);
+ object = PYGLIB_PyUnicode_FromString (string);
g_free (string);
@@ -1249,7 +1307,7 @@ _pygi_argument_to_object (GArgument *arg,
item_size = g_array_get_element_size (array);
for (i = 0; i < array->len; i++) {
- GArgument item;
+ GIArgument item;
PyObject *py_item;
gboolean is_struct = FALSE;
@@ -1266,9 +1324,9 @@ _pygi_argument_to_object (GArgument *arg,
}
if (is_struct) {
- item.v_pointer = &_g_array_index (array, GArgument, i);
+ item.v_pointer = &_g_array_index (array, GIArgument, i);
} else {
- memcpy (&item, &_g_array_index (array, GArgument, i), item_size);
+ memcpy (&item, &_g_array_index (array, GIArgument, i), item_size);
}
py_item = _pygi_argument_to_object (&item, item_type_info, item_transfer);
@@ -1355,15 +1413,12 @@ _pygi_argument_to_object (GArgument *arg,
break;
}
- if (transfer != GI_TRANSFER_NOTHING)
- g_warning ("Transfer mode should be set to None for "
- "struct types as there is no way to free "
- "them safely. Ignoring transfer mode "
- "to prevent a potential invalid free. "
- "This may cause a leak in your application.");
-
+ /* Only structs created in invoke can be safely marked
+ * GI_TRANSFER_EVERYTHING. Trust that invoke has
+ * filtered correctly
+ */
object = _pygi_struct_new ( (PyTypeObject *) py_type, arg->v_pointer,
- FALSE);
+ transfer == GI_TRANSFER_EVERYTHING);
Py_DECREF (py_type);
} else {
@@ -1446,7 +1501,7 @@ _pygi_argument_to_object (GArgument *arg,
item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
for (i = 0; list != NULL; list = g_slist_next (list), i++) {
- GArgument item;
+ GIArgument item;
PyObject *py_item;
item.v_pointer = list->data;
@@ -1470,8 +1525,8 @@ _pygi_argument_to_object (GArgument *arg,
GITypeInfo *value_type_info;
GITransfer item_transfer;
GHashTableIter hash_table_iter;
- GArgument key;
- GArgument value;
+ GIArgument key;
+ GIArgument value;
if (arg->v_pointer == NULL) {
object = Py_None;
@@ -1486,9 +1541,11 @@ _pygi_argument_to_object (GArgument *arg,
key_type_info = g_type_info_get_param_type (type_info, 0);
g_assert (key_type_info != NULL);
+ g_assert (g_type_info_get_tag (key_type_info) != GI_TYPE_TAG_VOID);
value_type_info = g_type_info_get_param_type (type_info, 1);
g_assert (value_type_info != NULL);
+ g_assert (g_type_info_get_tag (value_type_info) != GI_TYPE_TAG_VOID);
item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
@@ -1533,12 +1590,13 @@ _pygi_argument_to_object (GArgument *arg,
}
void
-_pygi_argument_release (GArgument *arg,
+_pygi_argument_release (GIArgument *arg,
GITypeInfo *type_info,
GITransfer transfer,
GIDirection direction)
{
GITypeTag type_tag;
+ gboolean is_out = (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT);
type_tag = g_type_info_get_tag (type_info);
@@ -1590,8 +1648,8 @@ _pygi_argument_release (GArgument *arg,
/* Free the items */
for (i = 0; i < array->len; i++) {
- GArgument *item;
- item = &_g_array_index (array, GArgument, i);
+ GIArgument *item;
+ item = &_g_array_index (array, GIArgument, i);
_pygi_argument_release (item, item_type_info, item_transfer, direction);
}
@@ -1649,7 +1707,7 @@ _pygi_argument_release (GArgument *arg,
}
} else if (g_struct_info_is_foreign ( (GIStructInfo*) info)) {
if (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING) {
- pygi_struct_foreign_release_g_argument (transfer, type_info, arg);
+ pygi_struct_foreign_release (info, arg->v_pointer);
}
} else if (g_type_is_a (type, G_TYPE_BOXED)) {
} else if (g_type_is_a (type, G_TYPE_POINTER) || type == G_TYPE_NONE) {
@@ -1666,7 +1724,7 @@ _pygi_argument_release (GArgument *arg,
if (arg->v_pointer == NULL) {
return;
}
- if (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING) {
+ if (is_out && transfer == GI_TRANSFER_EVERYTHING) {
g_object_unref (arg->v_pointer);
}
break;
@@ -1701,7 +1759,7 @@ _pygi_argument_release (GArgument *arg,
/* Free the items */
for (item = list; item != NULL; item = g_slist_next (item)) {
- _pygi_argument_release ( (GArgument *) &item->data, item_type_info,
+ _pygi_argument_release ( (GIArgument *) &item->data, item_type_info,
item_transfer, direction);
}
@@ -1754,9 +1812,9 @@ _pygi_argument_release (GArgument *arg,
g_hash_table_iter_init (&hash_table_iter, hash_table);
while (g_hash_table_iter_next (&hash_table_iter, &key, &value)) {
- _pygi_argument_release ( (GArgument *) &key, key_type_info,
+ _pygi_argument_release ( (GIArgument *) &key, key_type_info,
item_transfer, direction);
- _pygi_argument_release ( (GArgument *) &value, value_type_info,
+ _pygi_argument_release ( (GIArgument *) &value, value_type_info,
item_transfer, direction);
}
diff --git a/gi/pygi-argument.h b/gi/pygi-argument.h
index 821737a..d932e8f 100644
--- a/gi/pygi-argument.h
+++ b/gi/pygi-argument.h
@@ -30,6 +30,8 @@ G_BEGIN_DECLS
/* Private */
+gint _pygi_g_type_interface_check_object (GIBaseInfo *info,
+ PyObject *object);
gint _pygi_g_type_info_check_object (GITypeInfo *type_info,
PyObject *object,
@@ -40,21 +42,21 @@ gint _pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
PyObject *object);
-GArray* _pygi_argument_to_array (GArgument *arg,
- GArgument *args[],
+GArray* _pygi_argument_to_array (GIArgument *arg,
+ GIArgument *args[],
GITypeInfo *type_info,
gboolean is_method);
-GArgument _pygi_argument_from_object (PyObject *object,
+GIArgument _pygi_argument_from_object (PyObject *object,
GITypeInfo *type_info,
GITransfer transfer);
-PyObject* _pygi_argument_to_object (GArgument *arg,
+PyObject* _pygi_argument_to_object (GIArgument *arg,
GITypeInfo *type_info,
GITransfer transfer);
-void _pygi_argument_release (GArgument *arg,
+void _pygi_argument_release (GIArgument *arg,
GITypeInfo *type_info,
GITransfer transfer,
GIDirection direction);
diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c
index 4903834..2fd446c 100644
--- a/gi/pygi-boxed.c
+++ b/gi/pygi-boxed.c
@@ -25,6 +25,7 @@
#include <pygobject.h>
#include <girepository.h>
+#include <pyglib-python-compat.h>
static void
_boxed_dealloc (PyGIBoxed *self)
@@ -44,7 +45,38 @@ _boxed_dealloc (PyGIBoxed *self)
}
}
- ( (PyGObject *) self)->ob_type->tp_free ( (PyObject *) self);
+ Py_TYPE( (PyGObject *) self)->tp_free ( (PyObject *) self);
+}
+
+void *
+_pygi_boxed_alloc (GIBaseInfo *info, gsize *size_out)
+{
+ gsize size;
+
+ /* FIXME: Remove when bgo#622711 is fixed */
+ if (g_registered_type_info_get_g_type (info) == G_TYPE_VALUE) {
+ size = sizeof (GValue);
+ } else {
+ switch (g_base_info_get_type (info)) {
+ case GI_INFO_TYPE_UNION:
+ size = g_union_info_get_size ( (GIUnionInfo *) info);
+ break;
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ size = g_struct_info_get_size ( (GIStructInfo *) info);
+ break;
+ default:
+ PyErr_Format (PyExc_TypeError,
+ "info should be Boxed or Union, not '%d'",
+ g_base_info_get_type (info));
+ return NULL;
+ }
+ }
+
+ if( size_out != NULL)
+ *size_out = size;
+
+ return g_slice_alloc0 (size);
}
static PyObject *
@@ -55,7 +87,7 @@ _boxed_new (PyTypeObject *type,
static char *kwlist[] = { NULL };
GIBaseInfo *info;
- gsize size;
+ gsize size = 0;
gpointer boxed;
PyGIBoxed *self = NULL;
@@ -71,22 +103,7 @@ _boxed_new (PyTypeObject *type,
return NULL;
}
- switch (g_base_info_get_type (info)) {
- case GI_INFO_TYPE_UNION:
- size = g_union_info_get_size ( (GIUnionInfo *) info);
- break;
- case GI_INFO_TYPE_BOXED:
- case GI_INFO_TYPE_STRUCT:
- size = g_struct_info_get_size ( (GIStructInfo *) info);
- break;
- default:
- PyErr_Format (PyExc_TypeError,
- "info should be Boxed or Union, not '%d'",
- g_base_info_get_type (info));
- return NULL;
- }
-
- boxed = g_slice_alloc0 (size);
+ boxed = _pygi_boxed_alloc (info, &size);
if (boxed == NULL) {
PyErr_NoMemory();
goto out;
@@ -116,41 +133,7 @@ _boxed_init (PyObject *self,
return 0;
}
-
-PyTypeObject PyGIBoxed_Type = {
- PyObject_HEAD_INIT (NULL)
- 0,
- "gi.Boxed", /* tp_name */
- sizeof (PyGIBoxed), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) _boxed_dealloc, /* tp_dealloc */
- (printfunc) NULL, /* tp_print */
- (getattrfunc) NULL, /* tp_getattr */
- (setattrfunc) NULL, /* tp_setattr */
- (cmpfunc) NULL, /* tp_compare */
- (reprfunc) NULL, /* tp_repr */
- NULL, /* tp_as_number */
- NULL, /* tp_as_sequence */
- NULL, /* tp_as_mapping */
- (hashfunc) NULL, /* tp_hash */
- (ternaryfunc) NULL, /* tp_call */
- (reprfunc) NULL, /* tp_str */
- (getattrofunc) NULL, /* tp_getattro */
- (setattrofunc) NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- NULL, /* tp_doc */
- (traverseproc) NULL, /* tp_traverse */
- (inquiry) NULL, /* tp_clear */
- (richcmpfunc) NULL, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc) NULL, /* tp_iter */
- (iternextfunc) NULL, /* tp_iternext */
- NULL, /* tp_methods */
- NULL, /* tp_members */
- NULL, /* tp_getset */
- (PyTypeObject *) NULL, /* tp_base */
-};
+PYGLIB_DEFINE_TYPE("gi.Boxed", PyGIBoxed_Type, PyGIBoxed);
PyObject *
_pygi_boxed_new (PyTypeObject *type,
@@ -185,10 +168,13 @@ _pygi_boxed_new (PyTypeObject *type,
void
_pygi_boxed_register_types (PyObject *m)
{
- PyGIBoxed_Type.ob_type = &PyType_Type;
+ Py_TYPE(&PyGIBoxed_Type) = &PyType_Type;
PyGIBoxed_Type.tp_base = &PyGBoxed_Type;
PyGIBoxed_Type.tp_new = (newfunc) _boxed_new;
PyGIBoxed_Type.tp_init = (initproc) _boxed_init;
+ PyGIBoxed_Type.tp_dealloc = (destructor) _boxed_dealloc;
+ PyGIBoxed_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE);
+
if (PyType_Ready (&PyGIBoxed_Type))
return;
if (PyModule_AddObject (m, "Boxed", (PyObject *) &PyGIBoxed_Type))
diff --git a/gi/pygi-boxed.h b/gi/pygi-boxed.h
index 4f84060..a84ec4e 100644
--- a/gi/pygi-boxed.h
+++ b/gi/pygi-boxed.h
@@ -28,10 +28,12 @@ G_BEGIN_DECLS
extern PyTypeObject PyGIBoxed_Type;
-PyObject *
-_pygi_boxed_new (PyTypeObject *type,
- gpointer boxed,
- gboolean free_on_dealloc);
+PyObject * _pygi_boxed_new (PyTypeObject *type,
+ gpointer boxed,
+ gboolean free_on_dealloc);
+
+void * _pygi_boxed_alloc (GIBaseInfo *info,
+ gsize *size);
void _pygi_boxed_register_types (PyObject *m);
diff --git a/gi/pygi-callbacks.c b/gi/pygi-callbacks.c
index 6fdc1ce..bae4001 100644
--- a/gi/pygi-callbacks.c
+++ b/gi/pygi-callbacks.c
@@ -95,7 +95,8 @@ _pygi_scan_for_callbacks (GIFunctionInfo *function_info,
interface_type = g_base_info_get_type (interface_info);
if (interface_type == GI_INFO_TYPE_CALLBACK &&
! (strcmp (g_base_info_get_namespace ( (GIBaseInfo*) interface_info), "GLib") == 0 &&
- strcmp (g_base_info_get_name ( (GIBaseInfo*) interface_info), "DestroyNotify") == 0)) {
+ (strcmp (g_base_info_get_name ( (GIBaseInfo*) interface_info), "DestroyNotify") == 0 ||
+ (strcmp (g_base_info_get_name ( (GIBaseInfo*) interface_info), "FreeFunc") == 0)))) {
if (*callback_index != G_MAXUINT8) {
PyErr_Format (PyExc_TypeError, "Function %s.%s has multiple callbacks, not supported",
g_base_info_get_namespace ( (GIBaseInfo*) function_info),
@@ -108,11 +109,8 @@ _pygi_scan_for_callbacks (GIFunctionInfo *function_info,
g_base_info_unref (interface_info);
}
destroy = g_arg_info_get_destroy (arg_info);
- if (is_method)
- --destroy;
+
closure = g_arg_info_get_closure (arg_info);
- if (is_method)
- --closure;
direction = g_arg_info_get_direction (arg_info);
if (destroy > 0 && destroy < n_args) {
@@ -200,7 +198,8 @@ _pygi_create_callback (GIBaseInfo *function_info,
if (!found_py_function
|| (py_function == Py_None || !PyCallable_Check (py_function))) {
- PyErr_Format (PyExc_TypeError, "Error invoking %s.%s: Invalid callback given for argument %s",
+ PyErr_Format (PyExc_TypeError, "Error invoking %s.%s: Unexpected value "
+ "for argument '%s'",
g_base_info_get_namespace ( (GIBaseInfo*) function_info),
g_base_info_get_name ( (GIBaseInfo*) function_info),
g_base_info_get_name ( (GIBaseInfo*) callback_arg));
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index b26d5b1..1e2ce05 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -28,7 +28,7 @@
static GSList* async_free_list;
-static GArgument *
+static GIArgument *
_pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args)
{
gint num_args, i;
@@ -36,10 +36,10 @@ _pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args)
GITypeInfo *arg_type;
GITypeTag tag;
GIDirection direction;
- GArgument *g_args;
+ GIArgument *g_args;
num_args = g_callable_info_get_n_args (callable_info);
- g_args = g_new0 (GArgument, num_args);
+ g_args = g_new0 (GIArgument, num_args);
for (i = 0; i < num_args; i++) {
arg_info = g_callable_info_get_arg (callable_info, i);
@@ -130,13 +130,13 @@ _pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args)
static gboolean
_pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
void *user_data, PyObject **py_args,
- GArgument **out_args)
+ GIArgument **out_args)
{
int n_args = g_callable_info_get_n_args (callable_info);
int n_in_args = 0;
int n_out_args = 0;
int i;
- GArgument *g_args = NULL;
+ GIArgument *g_args = NULL;
*py_args = NULL;
*py_args = PyTuple_New (n_args);
@@ -144,7 +144,7 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
goto error;
*out_args = NULL;
- *out_args = g_new0 (GArgument, n_args);
+ *out_args = g_new0 (GIArgument, n_args);
g_args = _pygi_closure_convert_ffi_arguments (callable_info, args);
for (i = 0; i < n_args; i++) {
@@ -156,7 +156,7 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
GITypeTag arg_tag = g_type_info_get_tag (arg_type);
GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info);
PyObject *value;
- GArgument *arg;
+ GIArgument *arg;
if (direction == GI_DIRECTION_IN && arg_tag == GI_TYPE_TAG_VOID &&
g_type_info_is_pointer (arg_type)) {
@@ -170,9 +170,9 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
}
} else {
if (direction == GI_DIRECTION_IN)
- arg = (GArgument*) &g_args[i];
+ arg = (GIArgument*) &g_args[i];
else
- arg = (GArgument*) g_args[i].v_pointer;
+ arg = (GIArgument*) g_args[i].v_pointer;
value = _pygi_argument_to_object (arg, arg_type, transfer);
if (value == NULL) {
@@ -214,7 +214,7 @@ error:
static void
_pygi_closure_set_out_arguments (GICallableInfo *callable_info,
- PyObject *py_retval, GArgument *out_args,
+ PyObject *py_retval, GIArgument *out_args,
void *resp)
{
int n_args, i, i_py_retval, i_out_args;
@@ -225,15 +225,15 @@ _pygi_closure_set_out_arguments (GICallableInfo *callable_info,
return_type_info = g_callable_info_get_return_type (callable_info);
return_type_tag = g_type_info_get_tag (return_type_info);
if (return_type_tag != GI_TYPE_TAG_VOID) {
- GArgument arg;
+ GIArgument arg;
GITransfer transfer = g_callable_info_get_caller_owns (callable_info);
if (PyTuple_Check (py_retval)) {
PyObject *item = PyTuple_GET_ITEM (py_retval, 0);
arg = _pygi_argument_from_object (item, return_type_info, transfer);
- * ( (GArgument*) resp) = arg;
+ * ( (GIArgument*) resp) = arg;
} else {
arg = _pygi_argument_from_object (py_retval, return_type_info, transfer);
- * ( (GArgument*) resp) = arg;
+ * ( (GIArgument*) resp) = arg;
}
i_py_retval++;
}
@@ -248,14 +248,14 @@ _pygi_closure_set_out_arguments (GICallableInfo *callable_info,
if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info);
- GArgument arg;
+ GIArgument arg;
if (PyTuple_Check (py_retval)) {
PyObject *item = PyTuple_GET_ITEM (py_retval, i_py_retval);
arg = _pygi_argument_from_object (item, type_info, transfer);
- * ( (GArgument*) out_args[i_out_args].v_pointer) = arg;
+ * ( (GIArgument*) out_args[i_out_args].v_pointer) = arg;
} else if (i_py_retval == 0) {
arg = _pygi_argument_from_object (py_retval, type_info, transfer);
- * ( (GArgument*) out_args[i_out_args].v_pointer) = arg;
+ * ( (GIArgument*) out_args[i_out_args].v_pointer) = arg;
} else
g_assert_not_reached();
@@ -280,7 +280,7 @@ _pygi_closure_handle (ffi_cif *cif,
GITypeInfo *return_type;
PyObject *retval;
PyObject *py_args;
- GArgument *out_args = NULL;
+ GIArgument *out_args = NULL;
/* Lock the GIL as we are coming into this code without the lock and we
may be executing python code */
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 08d50ad..095f6cb 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -22,16 +22,24 @@
*/
#include <cairo.h>
+
+#if PY_VERSION_HEX < 0x03000000
#include <pycairo.h>
+#else
+#include <pycairo/py3cairo.h>
+#endif
+
Pycairo_CAPI_t *Pycairo_CAPI;
#include "pygi-foreign.h"
+#include <pyglib-python-compat.h>
+
PyObject *
cairo_context_to_arg (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
- GArgument *arg)
+ GIArgument *arg)
{
cairo_t *cr;
@@ -47,7 +55,7 @@ cairo_context_to_arg (PyObject *value,
}
PyObject *
-cairo_context_from_arg (GITypeInfo *type_info, GArgument *arg)
+cairo_context_from_arg (GITypeInfo *type_info, GIArgument *arg)
{
cairo_t *context = (cairo_t*) arg;
@@ -57,10 +65,10 @@ cairo_context_from_arg (GITypeInfo *type_info, GArgument *arg)
}
PyObject *
-cairo_context_release_arg (GITransfer transfer, GITypeInfo *type_info,
- GArgument *arg)
+cairo_context_release (GIBaseInfo *base_info,
+ gpointer struct_)
{
- cairo_destroy ( (cairo_t*) arg->v_pointer);
+ cairo_destroy ( (cairo_t*) struct_);
Py_RETURN_NONE;
}
@@ -69,7 +77,7 @@ PyObject *
cairo_surface_to_arg (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
- GArgument *arg)
+ GIArgument *arg)
{
cairo_surface_t *surface;
@@ -86,7 +94,7 @@ cairo_surface_to_arg (PyObject *value,
}
PyObject *
-cairo_surface_from_arg (GITypeInfo *type_info, GArgument *arg)
+cairo_surface_from_arg (GITypeInfo *type_info, GIArgument *arg)
{
cairo_surface_t *surface = (cairo_surface_t*) arg;
@@ -96,36 +104,31 @@ cairo_surface_from_arg (GITypeInfo *type_info, GArgument *arg)
}
PyObject *
-cairo_surface_release_arg (GITransfer transfer, GITypeInfo *type_info,
- GArgument *arg)
+cairo_surface_release (GIBaseInfo *base_info,
+ gpointer struct_)
{
- cairo_surface_destroy ( (cairo_surface_t*) arg->v_pointer);
+ cairo_surface_destroy ( (cairo_surface_t*) struct_);
Py_RETURN_NONE;
}
-PyMODINIT_FUNC
-init_gi_cairo (void)
-{
- PyObject *m;
-
- m = Py_InitModule ("_gi_cairo", NULL);
- if (m == NULL) {
- return;
- }
+static PyMethodDef _gi_cairo_functions[] = {};
+PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
+{
Pycairo_IMPORT;
if (Pycairo_CAPI == NULL)
- return;
+ return 0;
pygi_register_foreign_struct ("cairo",
"Context",
cairo_context_to_arg,
cairo_context_from_arg,
- cairo_context_release_arg);
+ cairo_context_release);
pygi_register_foreign_struct ("cairo",
"Surface",
cairo_surface_to_arg,
cairo_surface_from_arg,
- cairo_surface_release_arg);
+ cairo_surface_release);
}
+PYGLIB_MODULE_END;
diff --git a/gi/pygi-foreign-gvariant.c b/gi/pygi-foreign-gvariant.c
new file mode 100644
index 0000000..ac16395
--- /dev/null
+++ b/gi/pygi-foreign-gvariant.c
@@ -0,0 +1,63 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "pygobject.h"
+
+#include "pygi-private.h"
+#include "pygi-foreign-gvariant.h"
+
+PyObject *
+g_variant_to_arg (PyObject *value,
+ GITypeInfo *type_info,
+ GITransfer transfer,
+ GIArgument *arg)
+{
+ g_assert (transfer == GI_TRANSFER_NOTHING);
+
+ /* TODO check that value is a PyGPointer */
+
+ arg->v_pointer = (GVariant *) ( (PyGPointer *) value)->pointer;
+ Py_RETURN_NONE;
+}
+
+PyObject *
+g_variant_from_arg (GITypeInfo *type_info,
+ GIArgument *arg)
+{
+ GVariant *variant = (GVariant *) arg;
+ GITypeInfo *interface_info = g_type_info_get_interface (type_info);
+ PyObject *type = _pygi_type_import_by_gi_info (interface_info);
+
+ g_variant_ref_sink (variant);
+
+ return _pygi_struct_new ( (PyTypeObject *) type, variant, FALSE);
+}
+
+PyObject *
+g_variant_release_foreign (GIBaseInfo *base_info,
+ gpointer struct_)
+{
+ g_variant_unref ( (GVariant *) struct_);
+ Py_RETURN_NONE;
+}
+
diff --git a/gi/pygi-foreign-gvariant.h b/gi/pygi-foreign-gvariant.h
new file mode 100644
index 0000000..6de8c57
--- /dev/null
+++ b/gi/pygi-foreign-gvariant.h
@@ -0,0 +1,41 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __PYGI_FOREIGN_G_VARIANT_H__
+#define __PYGI_FOREIGN_G_VARIANT_H__
+
+#include "pygi-foreign.h"
+
+PyObject *g_variant_to_arg(PyObject *value,
+ GITypeInfo *type_info,
+ GITransfer transfer,
+ GIArgument *arg);
+
+PyObject *g_variant_from_arg(GITypeInfo *type_info,
+ GIArgument *arg);
+
+PyObject *g_variant_release_foreign (GIBaseInfo *base_info,
+ gpointer struct_);
+
+#endif /* __PYGI_FOREIGN_G_VARIANT_H__ */
+
diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c
index 13a0f77..f80b43c 100644
--- a/gi/pygi-foreign.c
+++ b/gi/pygi-foreign.c
@@ -23,6 +23,7 @@
*/
#include "pygi-foreign.h"
+#include "pygi-foreign-gvariant.h"
#include <config.h>
#include <girepository.h>
@@ -30,62 +31,87 @@
typedef struct {
const char *namespace;
const char *name;
- PyGIArgOverrideToGArgumentFunc to_func;
- PyGIArgOverrideFromGArgumentFunc from_func;
- PyGIArgOverrideReleaseGArgumentFunc release_func;
+ PyGIArgOverrideToGIArgumentFunc to_func;
+ PyGIArgOverrideFromGIArgumentFunc from_func;
+ PyGIArgOverrideReleaseFunc release_func;
} PyGIForeignStruct;
static GPtrArray *foreign_structs = NULL;
+void
+init_foreign_structs ()
+{
+ foreign_structs = g_ptr_array_new ();
+
+ pygi_register_foreign_struct ("GLib",
+ "Variant",
+ g_variant_to_arg,
+ g_variant_from_arg,
+ g_variant_release_foreign);
+}
+
static PyGIForeignStruct *
-pygi_struct_foreign_lookup (GITypeInfo *type_info)
+do_lookup (const gchar *namespace, const gchar *name)
{
gint i;
- PyObject *module;
- gchar *module_name;
- GIBaseInfo *base_info;
- const gchar *namespace;
- const gchar *name;
-
- base_info = g_type_info_get_interface (type_info);
- if (base_info == NULL) {
- PyErr_Format (PyExc_ValueError, "Couldn't resolve the type of this foreign struct");
- return NULL;
+ for (i = 0; i < foreign_structs->len; i++) {
+ PyGIForeignStruct *foreign_struct = \
+ g_ptr_array_index (foreign_structs, i);
+
+ if ( (strcmp (namespace, foreign_struct->namespace) == 0) &&
+ (strcmp (name, foreign_struct->name) == 0)) {
+ return foreign_struct;
+ }
+ }
+ return NULL;
+}
+
+static PyGIForeignStruct *
+pygi_struct_foreign_lookup (GIBaseInfo *base_info)
+{
+ 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 ();
}
- namespace = g_base_info_get_namespace (base_info);
- name = g_base_info_get_name (base_info);
+ result = do_lookup (namespace, name);
- module_name = g_strconcat ("gi._gi_", g_base_info_get_namespace (base_info), NULL);
- module = PyImport_ImportModule (module_name);
- g_free (module_name);
+ if (result == NULL) {
+ gchar *module_name = g_strconcat ("gi._gi_", namespace, NULL);
+ PyObject *module = PyImport_ImportModule (module_name);
- if (foreign_structs != NULL) {
- for (i = 0; i < foreign_structs->len; i++) {
- PyGIForeignStruct *foreign_struct = \
- g_ptr_array_index (foreign_structs, i);
+ g_free (module_name);
- if ( (strcmp (namespace, foreign_struct->namespace) == 0) &&
- (strcmp (name, foreign_struct->name) == 0)) {
- g_base_info_unref (base_info);
- return foreign_struct;
- }
+ if (module == NULL)
+ PyErr_Clear ();
+ else {
+ Py_DECREF (module);
+ result = do_lookup (namespace, name);
}
}
- g_base_info_unref (base_info);
+ if (result == NULL) {
+ PyErr_Format (PyExc_TypeError,
+ "Couldn't find conversion for foreign struct '%s.%s'",
+ namespace,
+ name);
+ }
- PyErr_Format (PyExc_TypeError, "Couldn't find conversion for foreign struct '%s.%s'", namespace, name);
- return NULL;
+ return result;
}
PyObject *
-pygi_struct_foreign_convert_to_g_argument (PyObject *value,
+pygi_struct_foreign_convert_to_g_argument (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
- GArgument *arg)
+ GIArgument *arg)
{
- PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info);
+ GIBaseInfo *base_info = g_type_info_get_interface (type_info);
+ PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info);
+ g_base_info_unref (base_info);
if (foreign_struct == NULL)
return NULL;
@@ -98,9 +124,12 @@ pygi_struct_foreign_convert_to_g_argument (PyObject *value,
PyObject *
pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info,
- GArgument *arg)
+ GIArgument *arg)
{
- PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info);
+ GIBaseInfo *base_info = g_type_info_get_interface (type_info);
+ PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info);
+ g_base_info_unref (base_info);
+
if (foreign_struct == NULL)
return NULL;
@@ -109,11 +138,10 @@ pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info,
}
PyObject *
-pygi_struct_foreign_release_g_argument (GITransfer transfer,
- GITypeInfo *type_info,
- GArgument *arg)
+pygi_struct_foreign_release (GIBaseInfo *base_info,
+ gpointer struct_)
{
- PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info);
+ PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info);
if (foreign_struct == NULL)
return NULL;
@@ -121,7 +149,7 @@ pygi_struct_foreign_release_g_argument (GITransfer transfer,
if (!foreign_struct->release_func)
Py_RETURN_NONE;
- if (!foreign_struct->release_func (transfer, type_info, arg))
+ if (!foreign_struct->release_func (base_info, struct_))
return NULL;
Py_RETURN_NONE;
@@ -130,9 +158,9 @@ pygi_struct_foreign_release_g_argument (GITransfer transfer,
void
pygi_register_foreign_struct_real (const char* namespace_,
const char* name,
- PyGIArgOverrideToGArgumentFunc to_func,
- PyGIArgOverrideFromGArgumentFunc from_func,
- PyGIArgOverrideReleaseGArgumentFunc release_func)
+ PyGIArgOverrideToGIArgumentFunc to_func,
+ PyGIArgOverrideFromGIArgumentFunc from_func,
+ PyGIArgOverrideReleaseFunc release_func)
{
PyGIForeignStruct *new_struct = g_slice_new0 (PyGIForeignStruct);
new_struct->namespace = namespace_;
@@ -141,8 +169,5 @@ pygi_register_foreign_struct_real (const char* namespace_,
new_struct->from_func = from_func;
new_struct->release_func = release_func;
- if (foreign_structs == NULL)
- foreign_structs = g_ptr_array_new ();
-
g_ptr_array_add (foreign_structs, new_struct);
}
diff --git a/gi/pygi-foreign.h b/gi/pygi-foreign.h
index 9a35bd8..b57f892 100644
--- a/gi/pygi-foreign.h
+++ b/gi/pygi-foreign.h
@@ -33,17 +33,16 @@
PyObject *pygi_struct_foreign_convert_to_g_argument (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
- GArgument *arg);
+ GIArgument *arg);
PyObject *pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info,
- GArgument *arg);
-PyObject *pygi_struct_foreign_release_g_argument (GITransfer transfer,
- GITypeInfo *type_info,
- GArgument *arg);
+ GIArgument *arg);
+PyObject *pygi_struct_foreign_release (GITypeInfo *type_info,
+ gpointer struct_);
void pygi_register_foreign_struct_real (const char* namespace_,
const char* name,
- PyGIArgOverrideToGArgumentFunc to_func,
- PyGIArgOverrideFromGArgumentFunc from_func,
- PyGIArgOverrideReleaseGArgumentFunc release_func);
+ PyGIArgOverrideToGIArgumentFunc to_func,
+ PyGIArgOverrideFromGIArgumentFunc from_func,
+ PyGIArgOverrideReleaseFunc release_func);
#endif /* __PYGI_FOREIGN_H__ */
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 7888ada..feeccf7 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -24,44 +24,7 @@
#include "pygi-private.h"
#include <pygobject.h>
-
-#define _PyGI_DEFINE_INFO_TYPE(name, cname, base) \
-static PyMethodDef _Py##cname##_methods[]; \
-PyTypeObject Py##cname##_Type = { \
- PyObject_HEAD_INIT(NULL) \
- 0, \
- "gi." name, /* tp_name */ \
- sizeof(PyGIBaseInfo), /* tp_basicsize */ \
- 0, /* tp_itemsize */ \
- (destructor)NULL, /* tp_dealloc */ \
- (printfunc)NULL, /* tp_print */ \
- (getattrfunc)NULL, /* tp_getattr */ \
- (setattrfunc)NULL, /* tp_setattr */ \
- (cmpfunc)NULL, /* tp_compare */ \
- (reprfunc)NULL, /* tp_repr */ \
- NULL, /* tp_as_number */ \
- NULL, /* tp_as_sequence */ \
- NULL, /* tp_as_mapping */ \
- (hashfunc)NULL, /* tp_hash */ \
- (ternaryfunc)NULL, /* tp_call */ \
- (reprfunc)NULL, /* tp_str */ \
- (getattrofunc)NULL, /* tp_getattro */ \
- (setattrofunc)NULL, /* tp_setattro */ \
- NULL, /* tp_as_buffer */ \
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ \
- NULL, /* tp_doc */ \
- (traverseproc)NULL, /* tp_traverse */ \
- (inquiry)NULL, /* tp_clear */ \
- (richcmpfunc)NULL, /* tp_richcompare */ \
- offsetof(PyGIBaseInfo, inst_weakreflist), /* tp_weaklistoffset */ \
- (getiterfunc)NULL, /* tp_iter */ \
- (iternextfunc)NULL, /* tp_iternext */ \
- _Py##cname##_methods, /* tp_methods */ \
- NULL, /* tp_members */ \
- NULL, /* tp_getset */ \
- &base /* tp_base */ \
-}
-
+#include <pyglib-python-compat.h>
/* BaseInfo */
@@ -74,7 +37,7 @@ _base_info_dealloc (PyGIBaseInfo *self)
g_base_info_unref (self->info);
- self->ob_type->tp_free ( (PyObject *) self);
+ Py_TYPE( (PyObject *) self)->tp_free ( (PyObject *) self);
}
static int
@@ -88,55 +51,26 @@ _base_info_traverse (PyGIBaseInfo *self,
static PyObject *
_base_info_repr (PyGIBaseInfo *self)
{
- return PyString_FromFormat ("<%s object (%s) at 0x%p>",
- self->ob_type->tp_name, g_base_info_get_name (self->info), (void *) self);
+ return PYGLIB_PyUnicode_FromFormat ("<%s object (%s) at 0x%p>",
+ Py_TYPE( (PyObject *) self)->tp_name,
+ g_base_info_get_name (self->info),
+ (void *) self);
}
static PyMethodDef _PyGIBaseInfo_methods[];
-PyTypeObject PyGIBaseInfo_Type = {
- PyObject_HEAD_INIT (NULL)
- 0,
- "gi.BaseInfo", /* tp_name */
- sizeof (PyGIBaseInfo), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) _base_info_dealloc, /* tp_dealloc */
- (printfunc) NULL, /* tp_print */
- (getattrfunc) NULL, /* tp_getattr */
- (setattrfunc) NULL, /* tp_setattr */
- (cmpfunc) NULL, /* tp_compare */
- (reprfunc) _base_info_repr, /* tp_repr */
- NULL, /* tp_as_number */
- NULL, /* tp_as_sequence */
- NULL, /* tp_as_mapping */
- (hashfunc) NULL, /* tp_hash */
- (ternaryfunc) NULL, /* tp_call */
- (reprfunc) NULL, /* tp_str */
- (getattrofunc) NULL, /* tp_getattro */
- (setattrofunc) NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
- Py_TPFLAGS_HAVE_GC, /* tp_flags */
- NULL, /* tp_doc */
- (traverseproc) _base_info_traverse, /* tp_traverse */
- (inquiry) NULL, /* tp_clear */
- (richcmpfunc) NULL, /* tp_richcompare */
- offsetof (PyGIBaseInfo, inst_weakreflist), /* tp_weaklistoffset */
- (getiterfunc) NULL, /* tp_iter */
- (iternextfunc) NULL, /* tp_iternext */
- _PyGIBaseInfo_methods, /* tp_methods */
-};
+PYGLIB_DEFINE_TYPE("gi.BaseInfo", PyGIBaseInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_base_info_get_name (PyGIBaseInfo *self)
{
- return PyString_FromString (g_base_info_get_name (self->info));
+ return PYGLIB_PyUnicode_FromString (g_base_info_get_name (self->info));
}
static PyObject *
_wrap_g_base_info_get_namespace (PyGIBaseInfo *self)
{
- return PyString_FromString (g_base_info_get_namespace (self->info));
+ return PYGLIB_PyUnicode_FromString (g_base_info_get_namespace (self->info));
}
static PyObject *
@@ -255,7 +189,7 @@ _pygi_object_get_gi_info (PyObject *object,
}
if (!PyObject_TypeCheck (py_info, type)) {
PyErr_Format (PyExc_TypeError, "attribute '__info__' must be %s, not %s",
- type->tp_name, py_info->ob_type->tp_name);
+ type->tp_name, Py_TYPE(&py_info)->tp_name);
goto out;
}
@@ -270,7 +204,7 @@ out:
/* CallableInfo */
-_PyGI_DEFINE_INFO_TYPE ("CallableInfo", GICallableInfo, PyGIBaseInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.CallableInfo", PyGICallableInfo_Type, PyGIBaseInfo);
static PyMethodDef _PyGICallableInfo_methods[] = {
{ NULL, NULL, 0 }
@@ -278,7 +212,7 @@ static PyMethodDef _PyGICallableInfo_methods[] = {
/* FunctionInfo */
-_PyGI_DEFINE_INFO_TYPE ("FunctionInfo", GIFunctionInfo, PyGICallableInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.FunctionInfo", PyGIFunctionInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_function_info_is_constructor (PyGIBaseInfo *self)
@@ -467,7 +401,7 @@ static PyMethodDef _PyGIFunctionInfo_methods[] = {
/* RegisteredTypeInfo */
-_PyGI_DEFINE_INFO_TYPE ("RegisteredTypeInfo", GIRegisteredTypeInfo, PyGIBaseInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.RegisteredTypeInfo", PyGIRegisteredTypeInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_registered_type_info_get_g_type (PyGIBaseInfo *self)
@@ -486,7 +420,7 @@ static PyMethodDef _PyGIRegisteredTypeInfo_methods[] = {
/* GIStructInfo */
-_PyGI_DEFINE_INFO_TYPE ("StructInfo", GIStructInfo, PyGIRegisteredTypeInfo_Type);
+PYGLIB_DEFINE_TYPE ("StructInfo", PyGIStructInfo_Type, PyGIBaseInfo);
static PyObject *
_get_fields (PyGIBaseInfo *self, GIInfoType info_type)
@@ -832,7 +766,7 @@ pygi_g_struct_info_is_simple (GIStructInfo *struct_info)
/* EnumInfo */
-_PyGI_DEFINE_INFO_TYPE ("EnumInfo", GIEnumInfo, PyGIRegisteredTypeInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.EnumInfo", PyGIEnumInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_enum_info_get_values (PyGIBaseInfo *self)
@@ -877,7 +811,7 @@ static PyMethodDef _PyGIEnumInfo_methods[] = {
/* ObjectInfo */
-_PyGI_DEFINE_INFO_TYPE ("ObjectInfo", GIObjectInfo, PyGIRegisteredTypeInfo_Type);
+PYGLIB_DEFINE_TYPE ("ObjectInfo", PyGIObjectInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_object_info_get_parent (PyGIBaseInfo *self)
@@ -970,7 +904,7 @@ static PyMethodDef _PyGIObjectInfo_methods[] = {
/* GIInterfaceInfo */
-_PyGI_DEFINE_INFO_TYPE ("InterfaceInfo", GIInterfaceInfo, PyGIRegisteredTypeInfo_Type);
+PYGLIB_DEFINE_TYPE ("InterfaceInfo", PyGIInterfaceInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_interface_info_get_methods (PyGIBaseInfo *self)
@@ -1028,13 +962,13 @@ static PyMethodDef _PyGIInterfaceInfo_methods[] = {
};
/* GIConstantInfo */
-_PyGI_DEFINE_INFO_TYPE ("ConstantInfo", GIConstantInfo, PyGIBaseInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.ConstantInfo", PyGIConstantInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_constant_info_get_value (PyGIBaseInfo *self)
{
GITypeInfo *type_info;
- GArgument value;
+ GIArgument value;
PyObject *py_value;
if (g_constant_info_get_value ( (GIConstantInfo *) self->info, &value) < 0) {
@@ -1057,7 +991,7 @@ static PyMethodDef _PyGIConstantInfo_methods[] = {
};
/* GIValueInfo */
-_PyGI_DEFINE_INFO_TYPE ("ValueInfo", GIValueInfo, PyGIBaseInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.ValueInfo", PyGIValueInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_value_info_get_value (PyGIBaseInfo *self)
@@ -1066,7 +1000,7 @@ _wrap_g_value_info_get_value (PyGIBaseInfo *self)
value = g_value_info_get_value ( (GIValueInfo *) self->info);
- return PyInt_FromLong (value);
+ return PYGLIB_PyLong_FromLong (value);
}
@@ -1077,7 +1011,7 @@ static PyMethodDef _PyGIValueInfo_methods[] = {
/* GIFieldInfo */
-_PyGI_DEFINE_INFO_TYPE ("FieldInfo", GIFieldInfo, PyGIBaseInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.FieldInfo", PyGIFieldInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_field_info_get_value (PyGIBaseInfo *self,
@@ -1088,10 +1022,10 @@ _wrap_g_field_info_get_value (PyGIBaseInfo *self,
GIInfoType container_info_type;
gpointer pointer;
GITypeInfo *field_type_info;
- GArgument value;
+ GIArgument value;
PyObject *py_value = NULL;
- memset(&value, 0, sizeof(GArgument));
+ memset(&value, 0, sizeof(GIArgument));
if (!PyArg_ParseTuple (args, "O:FieldInfo.get_value", &instance)) {
return NULL;
@@ -1197,7 +1131,7 @@ _wrap_g_field_info_set_value (PyGIBaseInfo *self,
GIInfoType container_info_type;
gpointer pointer;
GITypeInfo *field_type_info;
- GArgument value;
+ GIArgument value;
PyObject *retval = NULL;
if (!PyArg_ParseTuple (args, "OO:FieldInfo.set_value", &instance, &py_value)) {
@@ -1333,14 +1267,14 @@ static PyMethodDef _PyGIFieldInfo_methods[] = {
/* GIUnresolvedInfo */
-_PyGI_DEFINE_INFO_TYPE ("UnresolvedInfo", GIUnresolvedInfo, PyGIBaseInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.UnresolvedInfo", PyGIUnresolvedInfo_Type, PyGIBaseInfo);
static PyMethodDef _PyGIUnresolvedInfo_methods[] = {
{ NULL, NULL, 0 }
};
/* GIVFuncInfo */
-_PyGI_DEFINE_INFO_TYPE ("VFuncInfo", GIVFuncInfo, PyGIBaseInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.VFuncInfo", PyGIVFuncInfo_Type, PyGIBaseInfo);
static PyMethodDef _PyGIVFuncInfo_methods[] = {
{ NULL, NULL, 0 }
@@ -1348,7 +1282,7 @@ static PyMethodDef _PyGIVFuncInfo_methods[] = {
/* GIUnionInfo */
-_PyGI_DEFINE_INFO_TYPE ("UnionInfo", GIUnionInfo, PyGIRegisteredTypeInfo_Type);
+PYGLIB_DEFINE_TYPE ("gi.UnionInfo", PyGIUnionInfo_Type, PyGIBaseInfo);
static PyObject *
_wrap_g_union_info_get_fields (PyGIBaseInfo *self)
@@ -1458,27 +1392,61 @@ _pygi_g_base_info_get_fullname (GIBaseInfo *info)
void
_pygi_info_register_types (PyObject *m)
{
-#define _PyGI_REGISTER_TYPE(m, type, name) \
- type.ob_type = &PyType_Type; \
+#define _PyGI_REGISTER_TYPE(m, type, cname, base) \
+ Py_TYPE(&type) = &PyType_Type; \
+ type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE); \
+ type.tp_weaklistoffset = offsetof(PyGIBaseInfo, inst_weakreflist); \
+ type.tp_methods = _PyGI##cname##_methods; \
+ type.tp_base = &base; \
if (PyType_Ready(&type)) \
return; \
- if (PyModule_AddObject(m, name, (PyObject *)&type)) \
+ if (PyModule_AddObject(m, #cname, (PyObject *)&type)) \
return
- _PyGI_REGISTER_TYPE (m, PyGIBaseInfo_Type, "BaseInfo");
- _PyGI_REGISTER_TYPE (m, PyGIUnresolvedInfo_Type, "UnresolvedInfo");
- _PyGI_REGISTER_TYPE (m, PyGICallableInfo_Type, "CallableInfo");
- _PyGI_REGISTER_TYPE (m, PyGIFunctionInfo_Type, "FunctionInfo");
- _PyGI_REGISTER_TYPE (m, PyGIRegisteredTypeInfo_Type, "RegisteredTypeInfo");
- _PyGI_REGISTER_TYPE (m, PyGIStructInfo_Type, "StructInfo");
- _PyGI_REGISTER_TYPE (m, PyGIEnumInfo_Type, "EnumInfo");
- _PyGI_REGISTER_TYPE (m, PyGIObjectInfo_Type, "ObjectInfo");
- _PyGI_REGISTER_TYPE (m, PyGIInterfaceInfo_Type, "InterfaceInfo");
- _PyGI_REGISTER_TYPE (m, PyGIConstantInfo_Type, "ConstantInfo");
- _PyGI_REGISTER_TYPE (m, PyGIValueInfo_Type, "ValueInfo");
- _PyGI_REGISTER_TYPE (m, PyGIFieldInfo_Type, "FieldInfo");
- _PyGI_REGISTER_TYPE (m, PyGIVFuncInfo_Type, "VFuncInfo");
- _PyGI_REGISTER_TYPE (m, PyGIUnionInfo_Type, "UnionInfo");
+ Py_TYPE(&PyGIBaseInfo_Type) = &PyType_Type;
+
+ PyGIBaseInfo_Type.tp_dealloc = (destructor) _base_info_dealloc;
+ PyGIBaseInfo_Type.tp_repr = (reprfunc) _base_info_repr;
+ PyGIBaseInfo_Type.tp_flags = (Py_TPFLAGS_DEFAULT |
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC);
+ PyGIBaseInfo_Type.tp_traverse = (traverseproc) _base_info_traverse;
+ PyGIBaseInfo_Type.tp_weaklistoffset = offsetof(PyGIBaseInfo, inst_weakreflist);
+ PyGIBaseInfo_Type.tp_methods = _PyGIBaseInfo_methods;
+
+ if (PyType_Ready(&PyGIBaseInfo_Type))
+ return;
+
+ if (PyModule_AddObject(m, "BaseInfo", (PyObject *)&PyGIBaseInfo_Type))
+ return;
+
+ _PyGI_REGISTER_TYPE (m, PyGIUnresolvedInfo_Type, UnresolvedInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGICallableInfo_Type, CallableInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIFunctionInfo_Type, FunctionInfo,
+ PyGICallableInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIRegisteredTypeInfo_Type, RegisteredTypeInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIStructInfo_Type, StructInfo,
+ PyGIRegisteredTypeInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIEnumInfo_Type, EnumInfo,
+ PyGIRegisteredTypeInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIObjectInfo_Type, ObjectInfo,
+ PyGIRegisteredTypeInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIInterfaceInfo_Type, InterfaceInfo,
+ PyGIRegisteredTypeInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIConstantInfo_Type, ConstantInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIValueInfo_Type, ValueInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIFieldInfo_Type, FieldInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIVFuncInfo_Type, VFuncInfo,
+ PyGIBaseInfo_Type);
+ _PyGI_REGISTER_TYPE (m, PyGIUnionInfo_Type, UnionInfo,
+ PyGIRegisteredTypeInfo_Type);
+
#undef _PyGI_REGISTER_TYPE
}
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index a470003..64b3f31 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -49,14 +49,14 @@ struct invocation_state
GITypeInfo *return_type_info;
GITypeTag return_type_tag;
- GArgument **args;
+ GIArgument **args;
gboolean *args_is_auxiliary;
- GArgument *in_args;
- GArgument *out_args;
- GArgument *out_values;
- GArgument *backup_args;
- GArgument return_arg;
+ GIArgument *in_args;
+ GIArgument *out_args;
+ GIArgument *out_values;
+ GIArgument *backup_args;
+ GIArgument return_arg;
PyObject *return_value;
};
@@ -154,18 +154,14 @@ _prepare_invocation_state (struct invocation_state *state,
if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
state->n_in_args += 1;
- if (transfer == GI_TRANSFER_CONTAINER) {
- state->n_backup_args += 1;
- }
+ }
+ if (direction == GI_DIRECTION_INOUT) {
+ state->n_backup_args += 1;
}
if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
state->n_out_args += 1;
}
- if (direction == GI_DIRECTION_INOUT && transfer == GI_TRANSFER_NOTHING) {
- state->n_backup_args += 1;
- }
-
switch (arg_type_tag) {
case GI_TYPE_TAG_ARRAY:
{
@@ -173,13 +169,16 @@ _prepare_invocation_state (struct invocation_state *state,
length_arg_pos = g_type_info_get_array_length (state->arg_type_infos[i]);
- if (state->is_method)
- length_arg_pos--; // length_arg_pos refers to C args
-
if (length_arg_pos < 0) {
break;
}
+ /* For array lengths, we're going to delete the length argument;
+ * so remove the extra backup we just added above */
+ if (direction == GI_DIRECTION_INOUT) {
+ state->n_backup_args -= 1;
+ }
+
g_assert (length_arg_pos < state->n_args);
state->args_is_auxiliary[length_arg_pos] = TRUE;
@@ -208,9 +207,6 @@ _prepare_invocation_state (struct invocation_state *state,
gint length_arg_pos;
length_arg_pos = g_type_info_get_array_length (state->return_type_info);
- if (state->is_method)
- length_arg_pos--; // length_arg_pos refers to C args
-
if (length_arg_pos >= 0) {
g_assert (length_arg_pos < state->n_args);
state->args_is_auxiliary[length_arg_pos] = TRUE;
@@ -285,10 +281,10 @@ _prepare_invocation_state (struct invocation_state *state,
}
state->args = g_slice_alloc0 (sizeof (gpointer) * state->n_args);
- state->in_args = g_slice_alloc0 (sizeof (GArgument) * state->n_in_args);
- state->out_args = g_slice_alloc0 (sizeof (GArgument) * state->n_out_args);
- state->out_values = g_slice_alloc0 (sizeof (GArgument) * state->n_out_args);
- state->backup_args = g_slice_alloc0 (sizeof (GArgument) * state->n_backup_args);
+ state->in_args = g_slice_alloc0 (sizeof (GIArgument) * state->n_in_args);
+ state->out_args = g_slice_alloc0 (sizeof (GIArgument) * state->n_out_args);
+ state->out_values = g_slice_alloc0 (sizeof (GIArgument) * state->n_out_args);
+ state->backup_args = g_slice_alloc0 (sizeof (GIArgument) * state->n_backup_args);
/* Bind args so we can use an unique index. */
{
@@ -344,19 +340,15 @@ _prepare_invocation_state (struct invocation_state *state,
}
if (is_caller_allocates) {
- gsize size;
-
/* if caller allocates only use one level of indirection */
state->out_args[out_args_pos].v_pointer = NULL;
state->args[i] = &state->out_args[out_args_pos];
-
- /* FIXME: Remove when bgo#622711 is fixed */
- if (g_registered_type_info_get_g_type (info) == G_TYPE_VALUE)
- size = sizeof (GValue);
- else
- size = g_struct_info_get_size ( (GIStructInfo *) info);
-
- state->args[i]->v_pointer = g_malloc0 (size);
+ if (g_type_is_a (g_registered_type_info_get_g_type (info), G_TYPE_BOXED))
+ state->args[i]->v_pointer = _pygi_boxed_alloc (info, NULL);
+ else {
+ gssize size = g_struct_info_get_size ( (GIStructInfo *) info);
+ state->args[i]->v_pointer = g_malloc0 (size);
+ }
} else {
state->out_args[out_args_pos].v_pointer = &state->out_values[out_args_pos];
state->out_values[out_args_pos].v_pointer = NULL;
@@ -387,6 +379,7 @@ _prepare_invocation_state (struct invocation_state *state,
GIBaseInfo *container_info;
GIInfoType container_info_type;
PyObject *py_arg;
+ gint check_val;
container_info = g_base_info_get_container (function_info);
container_info_type = g_base_info_get_type (container_info);
@@ -394,6 +387,19 @@ _prepare_invocation_state (struct invocation_state *state,
g_assert (py_args_pos < state->n_py_args);
py_arg = PyTuple_GET_ITEM (py_args, py_args_pos);
+ /* In python 2 python takes care of checking the type
+ * of the self instance. In python 3 it does not
+ * so we have to check it here
+ */
+ check_val = _pygi_g_type_interface_check_object(container_info,
+ py_arg);
+ if (check_val < 0) {
+ return FALSE;
+ } else if (!check_val) {
+ _PyGI_ERROR_PREFIX ("instance: ");
+ return FALSE;
+ }
+
switch (container_info_type) {
case GI_INFO_TYPE_UNION:
case GI_INFO_TYPE_STRUCT:
@@ -487,61 +493,11 @@ _prepare_invocation_state (struct invocation_state *state,
return FALSE;
}
- if (direction == GI_DIRECTION_INOUT && transfer == GI_TRANSFER_NOTHING) {
+ if (direction == GI_DIRECTION_INOUT) {
/* We need to keep a copy of the argument to be able to release it later. */
g_assert (backup_args_pos < state->n_backup_args);
state->backup_args[backup_args_pos] = *state->args[i];
backup_args_pos += 1;
- } else if (transfer == GI_TRANSFER_CONTAINER) {
- /* We need to keep a copy of the items to be able to release them later. */
- switch (arg_type_tag) {
- case GI_TYPE_TAG_ARRAY:
- {
- GArray *array;
- gsize item_size;
- GArray *new_array;
-
- array = state->args[i]->v_pointer;
-
- item_size = g_array_get_element_size (array);
-
- new_array = g_array_sized_new (FALSE, FALSE, item_size, array->len);
- g_array_append_vals (new_array, array->data, array->len);
-
- g_assert (backup_args_pos < state->n_backup_args);
- state->backup_args[backup_args_pos].v_pointer = new_array;
-
- break;
- }
- case GI_TYPE_TAG_GLIST:
- g_assert (backup_args_pos < state->n_backup_args);
- state->backup_args[backup_args_pos].v_pointer = g_list_copy (state->args[i]->v_pointer);
- break;
- case GI_TYPE_TAG_GSLIST:
- g_assert (backup_args_pos < state->n_backup_args);
- state->backup_args[backup_args_pos].v_pointer = g_slist_copy (state->args[i]->v_pointer);
- break;
- case GI_TYPE_TAG_GHASH:
- {
- GHashTable *hash_table;
- GList *keys;
- GList *values;
-
- hash_table = state->args[i]->v_pointer;
-
- keys = g_hash_table_get_keys (hash_table);
- values = g_hash_table_get_values (hash_table);
-
- g_assert (backup_args_pos < state->n_backup_args);
- state->backup_args[backup_args_pos].v_pointer = g_list_concat (keys, values);
-
- break;
- }
- default:
- g_warn_if_reached();
- }
-
- backup_args_pos += 1;
}
if (arg_type_tag == GI_TYPE_TAG_ARRAY) {
@@ -551,8 +507,6 @@ _prepare_invocation_state (struct invocation_state *state,
array = state->args[i]->v_pointer;
length_arg_pos = g_type_info_get_array_length (state->arg_type_infos[i]);
- if (state->is_method)
- length_arg_pos--; // length_arg_pos refers to C args
if (length_arg_pos >= 0) {
int len = 0;
/* Set the auxiliary argument holding the length. */
@@ -639,6 +593,11 @@ _process_invocation_state (struct invocation_state *state,
GIInfoType info_type;
GITransfer transfer;
+ if (state->return_arg.v_pointer == NULL) {
+ PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
+ return FALSE;
+ }
+
g_assert (state->n_py_args > 0);
py_type = (PyTypeObject *) PyTuple_GET_ITEM (py_args, 0);
@@ -651,10 +610,6 @@ _process_invocation_state (struct invocation_state *state,
switch (info_type) {
case GI_INFO_TYPE_UNION:
- /* TODO */
- PyErr_SetString (PyExc_NotImplementedError, "creating unions is not supported yet");
- g_base_info_unref (info);
- return FALSE;
case GI_INFO_TYPE_STRUCT:
{
GType type;
@@ -662,24 +617,22 @@ _process_invocation_state (struct invocation_state *state,
type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
if (g_type_is_a (type, G_TYPE_BOXED)) {
- if (state->return_arg.v_pointer == NULL) {
- PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
- break;
- }
g_warn_if_fail (transfer == GI_TRANSFER_EVERYTHING);
state->return_value = _pygi_boxed_new (py_type, state->return_arg.v_pointer, transfer == GI_TRANSFER_EVERYTHING);
+ } else if (type == G_TYPE_NONE && g_struct_info_is_foreign (info)) {
+ state->return_value =
+ pygi_struct_foreign_convert_from_g_argument (
+ state->return_type_info, state->return_arg.v_pointer);
} else if (g_type_is_a (type, G_TYPE_POINTER) || type == G_TYPE_NONE) {
- if (state->return_arg.v_pointer == NULL) {
- PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
- break;
- }
-
if (transfer != GI_TRANSFER_NOTHING)
- g_warning ("Transfer mode should be set to None for "
+ g_warning ("Return argument in %s returns a struct "
+ "with a transfer mode of \"full\" "
+ "Transfer mode should be set to None for "
"struct types as there is no way to free "
"them safely. Ignoring transfer mode "
"to prevent a potential invalid free. "
- "This may cause a leak in your application.");
+ "This may cause a leak in your application.",
+ g_base_info_get_name ( (GIBaseInfo *) function_info) );
state->return_value = _pygi_struct_new (py_type, state->return_arg.v_pointer, FALSE);
} else {
@@ -740,10 +693,8 @@ _process_invocation_state (struct invocation_state *state,
/* Convert output arguments and release arguments. */
{
- gsize backup_args_pos;
gsize return_values_pos;
- backup_args_pos = 0;
return_values_pos = 0;
if (state->n_return_values > 1) {
@@ -795,6 +746,36 @@ _process_invocation_state (struct invocation_state *state,
/* Convert the argument. */
PyObject *obj;
+ /* If we created it, deallocate when it goes out of scope
+ * otherwise it is unsafe to deallocate random structures
+ * we are given
+ */
+ if (type_tag == GI_TYPE_TAG_INTERFACE) {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ info = g_type_info_get_interface (state->arg_type_infos[i]);
+ g_assert (info != NULL);
+ info_type = g_base_info_get_type (info);
+
+ if ( (info_type == GI_INFO_TYPE_STRUCT) &&
+ !g_struct_info_is_foreign((GIStructInfo *) info) ) {
+ if (g_arg_info_is_caller_allocates (state->arg_infos[i])) {
+ transfer = GI_TRANSFER_EVERYTHING;
+ } else if (transfer == GI_TRANSFER_EVERYTHING) {
+ transfer = GI_TRANSFER_NOTHING;
+ g_warning ("Out argument %ld in %s returns a struct "
+ "with a transfer mode of \"full\". "
+ "Transfer mode should be set to \"none\" for "
+ "struct type returns as there is no way to free "
+ "them safely. Ignoring transfer mode "
+ "to prevent a potential invalid free. "
+ "This may cause a leak in your application.",
+ i, g_base_info_get_name ( (GIBaseInfo *) function_info) );
+ }
+ }
+ }
+
obj = _pygi_argument_to_object (state->args[i], state->arg_type_infos[i], transfer);
if (obj == NULL) {
/* TODO: release arguments. */
@@ -814,83 +795,9 @@ _process_invocation_state (struct invocation_state *state,
return_values_pos += 1;
}
- /* Release the argument. */
-
- if ( (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT)
- && transfer == GI_TRANSFER_CONTAINER) {
- /* Release the items we kept in another container. */
- switch (type_tag) {
- case GI_TYPE_TAG_ARRAY:
- case GI_TYPE_TAG_GLIST:
- case GI_TYPE_TAG_GSLIST:
- g_assert (backup_args_pos < state->n_backup_args);
- _pygi_argument_release (&state->backup_args[backup_args_pos], state->arg_type_infos[i],
- transfer, GI_DIRECTION_IN);
- break;
- case GI_TYPE_TAG_GHASH:
- {
- GITypeInfo *key_type_info;
- GITypeInfo *value_type_info;
- GList *item;
- gsize length;
- gsize j;
-
- key_type_info = g_type_info_get_param_type (state->arg_type_infos[i], 0);
- value_type_info = g_type_info_get_param_type (state->arg_type_infos[i], 1);
-
- g_assert (backup_args_pos < state->n_backup_args);
- item = state->backup_args[backup_args_pos].v_pointer;
-
- length = g_list_length (item) / 2;
-
- for (j = 0; j < length; j++, item = g_list_next (item)) {
- _pygi_argument_release ( (GArgument *) &item->data, key_type_info,
- GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
- }
-
- for (j = 0; j < length; j++, item = g_list_next (item)) {
- _pygi_argument_release ( (GArgument *) &item->data, value_type_info,
- GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
- }
-
- g_list_free (state->backup_args[backup_args_pos].v_pointer);
-
- break;
- }
- default:
- g_warn_if_reached();
- }
-
- if (direction == GI_DIRECTION_INOUT) {
- /* Release the output argument. */
- _pygi_argument_release (state->args[i], state->arg_type_infos[i], GI_TRANSFER_CONTAINER,
- GI_DIRECTION_OUT);
- }
-
- backup_args_pos += 1;
- } else if (direction == GI_DIRECTION_INOUT) {
- if (transfer == GI_TRANSFER_NOTHING) {
- g_assert (backup_args_pos < state->n_backup_args);
- _pygi_argument_release (&state->backup_args[backup_args_pos], state->arg_type_infos[i],
- GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
- backup_args_pos += 1;
- }
-
- _pygi_argument_release (state->args[i], state->arg_type_infos[i], transfer,
- GI_DIRECTION_OUT);
- } else {
- _pygi_argument_release (state->args[i], state->arg_type_infos[i], transfer, direction);
- }
-
- if (type_tag == GI_TYPE_TAG_ARRAY
- && (direction != GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)) {
- /* We created a #GArray and it has not been released above, so free it. */
- state->args[i]->v_pointer = g_array_free (state->args[i]->v_pointer, FALSE);
- }
}
g_assert (state->n_return_values <= 1 || return_values_pos == state->n_return_values);
- g_assert (backup_args_pos == state->n_backup_args);
}
return TRUE;
@@ -900,6 +807,7 @@ static void
_free_invocation_state (struct invocation_state *state)
{
gsize i;
+ gsize backup_args_pos;
if (state->return_type_info != NULL) {
g_base_info_unref ( (GIBaseInfo *) state->return_type_info);
@@ -910,29 +818,42 @@ _free_invocation_state (struct invocation_state *state)
_pygi_invoke_closure_free (state->closure);
}
+ /* release all arguments. */
+ backup_args_pos = 0;
for (i = 0; i < state->n_args; i++) {
- /* check for caller-allocated values we need to free */
- if (g_arg_info_is_caller_allocates (state->arg_infos[i])) {
- GIBaseInfo *info;
- GIInfoType info_type;
+ if (state->args_is_auxiliary[i]) {
+ /* Auxiliary arguments are not released. */
+ continue;
+ }
- info = g_type_info_get_interface (state->arg_type_infos[i]);
- g_assert (info != NULL);
- info_type = g_base_info_get_type (info);
+ if (state->args != NULL
+ && state->args[i] != NULL
+ && state->arg_infos[i] != NULL
+ && state->arg_type_infos[i] != NULL) {
+ GIDirection direction;
+ GITypeTag type_tag;
+ GITransfer transfer;
- /* caller-allocates applies only to structs right now
- * the GI scanner is overzealous when marking parameters
- * as caller-allocates, so we only free if this was a struct
- */
- if (info_type == GI_INFO_TYPE_STRUCT) {
- /* special case GValues so we make sure to unset them */
- if (g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info) == G_TYPE_VALUE) {
- g_value_unset ( (GValue *) state->args[i]);
- }
+ direction = g_arg_info_get_direction (state->arg_infos[i]);
+ transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]);
+
+ type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
+
+ /* Release the argument. */
+ if (direction == GI_DIRECTION_INOUT) {
+ _pygi_argument_release (&state->backup_args[backup_args_pos], state->arg_type_infos[i],
+ transfer, GI_DIRECTION_IN);
+ backup_args_pos += 1;
+ }
+ _pygi_argument_release (state->args[i], state->arg_type_infos[i], transfer, direction);
- g_free (state->args[i]);
+ if (type_tag == GI_TYPE_TAG_ARRAY
+ && (direction != GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)) {
+ /* We created a #GArray and it has not been released above, so free it. */
+ state->args[i]->v_pointer = g_array_free (state->args[i]->v_pointer, FALSE);
}
+
}
if (state->arg_type_infos[i] != NULL)
@@ -940,37 +861,30 @@ _free_invocation_state (struct invocation_state *state)
if (state->arg_infos[i] != NULL)
g_base_info_unref ( (GIBaseInfo *) state->arg_infos[i]);
}
+ g_assert (backup_args_pos == state->n_backup_args);
- if (state->arg_infos != NULL) {
- g_slice_free1 (sizeof (gpointer) * state->n_args, state->arg_infos);
- }
-
- if (state->arg_type_infos != NULL) {
- g_slice_free1 (sizeof (gpointer) * state->n_args, state->arg_type_infos);
- }
+ g_slice_free1 (sizeof (gpointer) * state->n_args, state->arg_infos);
+ g_slice_free1 (sizeof (gpointer) * state->n_args, state->arg_type_infos);
+ g_slice_free1 (sizeof (gboolean) * state->n_args, state->args_is_auxiliary);
if (state->args != NULL) {
g_slice_free1 (sizeof (gpointer) * state->n_args, state->args);
}
- if (state->args_is_auxiliary != NULL) {
- g_slice_free1 (sizeof (gboolean) * state->n_args, state->args_is_auxiliary);
- }
-
if (state->in_args != NULL) {
- g_slice_free1 (sizeof (GArgument) * state->n_in_args, state->in_args);
+ g_slice_free1 (sizeof (GIArgument) * state->n_in_args, state->in_args);
}
if (state->out_args != NULL) {
- g_slice_free1 (sizeof (GArgument) * state->n_out_args, state->out_args);
+ g_slice_free1 (sizeof (GIArgument) * state->n_out_args, state->out_args);
}
if (state->out_values != NULL) {
- g_slice_free1 (sizeof (GArgument) * state->n_out_args, state->out_values);
+ g_slice_free1 (sizeof (GIArgument) * state->n_out_args, state->out_values);
}
if (state->backup_args != NULL) {
- g_slice_free1 (sizeof (GArgument) * state->n_backup_args, state->backup_args);
+ g_slice_free1 (sizeof (GIArgument) * state->n_backup_args, state->backup_args);
}
if (PyErr_Occurred()) {
@@ -1001,6 +915,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self, PyObject *py_args)
return NULL;
}
+ _free_invocation_state (&state);
return state.return_value;
}
diff --git a/gi/pygi-private.h b/gi/pygi-private.h
index 0ff5df7..3a14bc3 100644
--- a/gi/pygi-private.h
+++ b/gi/pygi-private.h
@@ -28,8 +28,30 @@
#include "pygi-closure.h"
#include "pygi-callbacks.h"
#include "pygi-invoke.h"
+#include "pygi-property.h"
G_BEGIN_DECLS
+#if PY_VERSION_HEX >= 0x03000000
+
+#define _PyGI_ERROR_PREFIX(format, ...) G_STMT_START { \
+ PyObject *py_error_prefix; \
+ py_error_prefix = PyUnicode_FromFormat(format, ## __VA_ARGS__); \
+ if (py_error_prefix != NULL) { \
+ PyObject *py_error_type, *py_error_value, *py_error_traceback; \
+ PyErr_Fetch(&py_error_type, &py_error_value, &py_error_traceback); \
+ if (PyUnicode_Check(py_error_value)) { \
+ PyObject *new; \
+ new = PyUnicode_Concat(py_error_prefix, py_error_value); \
+ Py_DECREF(py_error_value); \
+ if (new != NULL) { \
+ py_error_value = new; \
+ } \
+ } \
+ PyErr_Restore(py_error_type, py_error_value, py_error_traceback); \
+ } \
+} G_STMT_END
+
+#else
#define _PyGI_ERROR_PREFIX(format, ...) G_STMT_START { \
PyObject *py_error_prefix; \
@@ -47,6 +69,8 @@ G_BEGIN_DECLS
} \
} G_STMT_END
+#endif
+
/* Redefine g_array_index because we want it to return the i-th element, casted
* to the type t, of the array a, and not the i-th element of the array a
* casted to the type t. */
diff --git a/gi/pygi-property.c b/gi/pygi-property.c
new file mode 100644
index 0000000..7b6a508
--- /dev/null
+++ b/gi/pygi-property.c
@@ -0,0 +1,345 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "pygi-private.h"
+
+#include <girepository.h>
+
+/* Copied from glib */
+static void
+canonicalize_key (gchar *key)
+{
+ gchar *p;
+
+ for (p = key; *p != 0; p++)
+ {
+ gchar c = *p;
+
+ if (c != '-' &&
+ (c < '0' || c > '9') &&
+ (c < 'A' || c > 'Z') &&
+ (c < 'a' || c > 'z'))
+ *p = '-';
+ }
+}
+
+static GIPropertyInfo *
+_pygi_lookup_property_from_g_type (GType g_type, const gchar *attr_name)
+{
+ GIRepository *repository;
+ GIBaseInfo *info;
+ gssize n_infos;
+ gssize i;
+ GType parent;
+
+ repository = g_irepository_get_default();
+ info = g_irepository_find_by_gtype (repository, g_type);
+ if (info == NULL) {
+ return NULL;
+ }
+
+ n_infos = g_object_info_get_n_properties ( (GIObjectInfo *) info);
+ for (i = 0; i < n_infos; i++) {
+ GIPropertyInfo *property_info;
+
+ property_info = g_object_info_get_property ( (GIObjectInfo *) info, i);
+ g_assert (info != NULL);
+
+ if (strcmp (attr_name, g_base_info_get_name (property_info)) == 0) {
+ g_base_info_unref (info);
+ return property_info;
+ }
+
+ g_base_info_unref (property_info);
+ }
+
+ g_base_info_unref (info);
+
+ parent = g_type_parent (g_type);
+ if (parent > 0)
+ return _pygi_lookup_property_from_g_type (parent, attr_name);
+
+ return NULL;
+}
+
+PyObject *
+pygi_get_property_value_real (PyGObject *instance,
+ const gchar *attr_name)
+{
+ GType g_type;
+ GIPropertyInfo *property_info = NULL;
+ char *property_name = g_strdup (attr_name);
+ GParamSpec *pspec = NULL;
+ GValue value = { 0, };
+ GIArgument arg = { 0, };
+ PyObject *py_value = NULL;
+ GITypeInfo *type_info = NULL;
+ GITransfer transfer;
+
+ canonicalize_key (property_name);
+
+ g_type = pyg_type_from_object ((PyObject *)instance);
+ property_info = _pygi_lookup_property_from_g_type (g_type, property_name);
+
+ if (property_info == NULL)
+ goto out;
+
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (instance->obj),
+ attr_name);
+ if (pspec == NULL)
+ goto out;
+
+ g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_object_get_property (instance->obj, attr_name, &value);
+
+ type_info = g_property_info_get_type (property_info);
+ transfer = g_property_info_get_ownership_transfer (property_info);
+
+ GITypeTag type_tag = g_type_info_get_tag (type_info);
+ switch (type_tag) {
+ case GI_TYPE_TAG_BOOLEAN:
+ arg.v_boolean = g_value_get_boolean (&value);
+ break;
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_INT64:
+ arg.v_int = g_value_get_int (&value);
+ break;
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_UINT64:
+ arg.v_uint = g_value_get_uint (&value);
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ arg.v_float = g_value_get_float (&value);
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ arg.v_double = g_value_get_double (&value);
+ break;
+ case GI_TYPE_TAG_GTYPE:
+ arg.v_size = g_value_get_uint (&value);
+ break;
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ arg.v_string = g_value_dup_string (&value);
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+ GType type;
+
+ info = g_type_info_get_interface (type_info);
+ type = g_registered_type_info_get_g_type (info);
+ info_type = g_base_info_get_type (info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_ENUM:
+ arg.v_int32 = g_value_get_enum (&value);
+ break;
+ case GI_INFO_TYPE_INTERFACE:
+ case GI_INFO_TYPE_OBJECT:
+ arg.v_pointer = g_value_get_object (&value);
+ break;
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ case GI_INFO_TYPE_UNION:
+
+ if (g_type_is_a (type, G_TYPE_BOXED)) {
+ arg.v_pointer = g_value_get_boxed (&value);
+ } else if (g_type_is_a (type, G_TYPE_POINTER)) {
+ arg.v_pointer = g_value_get_pointer (&value);
+ } else {
+ PyErr_Format (PyExc_NotImplementedError,
+ "Retrieving properties of type '%s' is not implemented",
+ g_type_name (type));
+ }
+ break;
+ default:
+ PyErr_Format (PyExc_NotImplementedError,
+ "Retrieving properties of type '%s' is not implemented",
+ g_type_name (type));
+ goto out;
+ }
+ break;
+ }
+ case GI_TYPE_TAG_GHASH:
+ arg.v_pointer = g_value_get_boxed (&value);
+ break;
+ case GI_TYPE_TAG_GLIST:
+ arg.v_pointer = g_value_get_pointer (&value);
+ break;
+ default:
+ PyErr_Format (PyExc_NotImplementedError,
+ "Retrieving properties of type %s is not implemented",
+ g_type_tag_to_string (g_type_info_get_tag (type_info)));
+ goto out;
+ }
+
+ py_value = _pygi_argument_to_object (&arg, type_info, transfer);
+
+out:
+ g_free (property_name);
+ if (property_info != NULL)
+ g_base_info_unref (property_info);
+ if (type_info != NULL)
+ g_base_info_unref (type_info);
+
+ return py_value;
+}
+
+gint
+pygi_set_property_value_real (PyGObject *instance,
+ const gchar *attr_name,
+ PyObject *py_value)
+{
+ GType g_type;
+ GIPropertyInfo *property_info = NULL;
+ char *property_name = g_strdup (attr_name);
+ GITypeInfo *type_info = NULL;
+ GITypeTag type_tag;
+ GITransfer transfer;
+ GValue value = { 0, };
+ GIArgument arg = { 0, };
+ GParamSpec *pspec = NULL;
+ gint ret_value = -1;
+
+ canonicalize_key (property_name);
+
+ g_type = pyg_type_from_object ((PyObject *)instance);
+ property_info = _pygi_lookup_property_from_g_type (g_type, property_name);
+
+ if (property_info == NULL)
+ goto out;
+
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (instance->obj),
+ attr_name);
+ if (pspec == NULL)
+ goto out;
+
+ if (! (pspec->flags & G_PARAM_WRITABLE))
+ goto out;
+
+ type_info = g_property_info_get_type (property_info);
+ transfer = g_property_info_get_ownership_transfer (property_info);
+ arg = _pygi_argument_from_object (py_value, type_info, transfer);
+
+ g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+
+ // FIXME: Lots of types still unhandled
+ type_tag = g_type_info_get_tag (type_info);
+ switch (type_tag) {
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+ GType type;
+
+ info = g_type_info_get_interface (type_info);
+ type = g_registered_type_info_get_g_type (info);
+ info_type = g_base_info_get_type (info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_ENUM:
+ g_value_set_enum (&value, arg.v_int32);
+ break;
+ case GI_INFO_TYPE_INTERFACE:
+ case GI_INFO_TYPE_OBJECT:
+ g_value_set_object (&value, arg.v_pointer);
+ break;
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ case GI_INFO_TYPE_UNION:
+ if (g_type_is_a (type, G_TYPE_BOXED)) {
+ g_value_set_boxed (&value, arg.v_pointer);
+ } else {
+ PyErr_Format (PyExc_NotImplementedError,
+ "Setting properties of type '%s' is not implemented",
+ g_type_name (type));
+ }
+ break;
+ default:
+ PyErr_Format (PyExc_NotImplementedError,
+ "Setting properties of type '%s' is not implemented",
+ g_type_name (type));
+ goto out;
+ }
+ break;
+ }
+ case GI_TYPE_TAG_BOOLEAN:
+ g_value_set_boolean (&value, arg.v_boolean);
+ break;
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_INT64:
+ g_value_set_int (&value, arg.v_int);
+ break;
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_UINT64:
+ g_value_set_uint (&value, arg.v_uint);
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ g_value_set_float (&value, arg.v_float);
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ g_value_set_double (&value, arg.v_double);
+ break;
+ case GI_TYPE_TAG_GTYPE:
+ g_value_set_uint (&value, arg.v_size);
+ break;
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ g_value_set_string (&value, arg.v_string);
+ break;
+ case GI_TYPE_TAG_GHASH:
+ g_value_set_boxed (&value, arg.v_pointer);
+ break;
+ case GI_TYPE_TAG_GLIST:
+ g_value_set_pointer (&value, arg.v_pointer);
+ break;
+ default:
+ PyErr_Format (PyExc_NotImplementedError,
+ "Setting properties of type %s is not implemented",
+ g_type_tag_to_string (g_type_info_get_tag (type_info)));
+ goto out;
+ }
+
+ g_object_set_property (instance->obj, attr_name, &value);
+
+ ret_value = 0;
+
+out:
+ g_free (property_name);
+ if (property_info != NULL)
+ g_base_info_unref (property_info);
+ if (type_info != NULL)
+ g_base_info_unref (type_info);
+
+ return ret_value;
+}
+
diff --git a/gi/pygi-property.h b/gi/pygi-property.h
new file mode 100644
index 0000000..31d0e42
--- /dev/null
+++ b/gi/pygi-property.h
@@ -0,0 +1,39 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __PYGI_PROPERTY_H__
+#define __PYGI_PROPERTY_H__
+
+#include <Python.h>
+#include <girepository.h>
+
+#include "pygi.h"
+
+PyObject *pygi_get_property_value_real (PyGObject *instance,
+ const gchar *attr_name);
+
+gint pygi_set_property_value_real (PyGObject *instance,
+ const gchar *attr_name,
+ PyObject *py_value);
+
+#endif /* __PYGI_PROPERTY_H__ */
diff --git a/gi/pygi-repository.c b/gi/pygi-repository.c
index 783b4aa..9b22eae 100644
--- a/gi/pygi-repository.c
+++ b/gi/pygi-repository.c
@@ -23,41 +23,42 @@
#include "pygi-private.h"
+#include <pyglib-python-compat.h>
+
PyObject *PyGIRepositoryError;
static PyMethodDef _PyGIRepository_methods[];
-PyTypeObject PyGIRepository_Type = {
- PyObject_HEAD_INIT (NULL)
- 0,
- "gi.Repository", /* tp_name */
- sizeof (PyGIRepository), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) NULL, /* tp_dealloc */
- (printfunc) NULL, /* tp_print */
- (getattrfunc) NULL, /* tp_getattr */
- (setattrfunc) NULL, /* tp_setattr */
- (cmpfunc) NULL, /* tp_compare */
- (reprfunc) NULL, /* tp_repr */
- NULL, /* tp_as_number */
- NULL, /* tp_as_sequence */
- NULL, /* tp_as_mapping */
- (hashfunc) NULL, /* tp_hash */
- (ternaryfunc) NULL, /* tp_call */
- (reprfunc) NULL, /* tp_str */
- (getattrofunc) NULL, /* tp_getattro */
- (setattrofunc) NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- NULL, /* tp_doc */
- (traverseproc) NULL, /* tp_traverse */
- (inquiry) NULL, /* tp_clear */
- (richcmpfunc) NULL, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc) NULL, /* tp_iter */
- (iternextfunc) NULL, /* tp_iternext */
- _PyGIRepository_methods, /* tp_methods */
-};
+PYGLIB_DEFINE_TYPE("gi.Repository", PyGIRepository_Type, PyGIRepository);
+
+static PyObject *
+_wrap_g_irepository_enumerate_versions (PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", NULL };
+ const char *namespace_;
+ GList *versions, *item;
+ PyObject *ret = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s:Repository.enumerate_versions",
+ kwlist, &namespace_)) {
+ return NULL;
+ }
+
+ versions = g_irepository_enumerate_versions (self->repository, namespace_);
+ ret = PyList_New(0);
+ for (item = versions; item; item = item->next) {
+ char *version = item->data;
+ PyObject *py_version = PYGLIB_PyUnicode_FromString (version);
+ PyList_Append(ret, py_version);
+ Py_DECREF(py_version);
+ g_free (version);
+ }
+ g_list_free(versions);
+
+ return ret;
+}
static PyObject *
_wrap_g_irepository_get_default (PyObject *self)
@@ -91,7 +92,7 @@ _wrap_g_irepository_require (PyGIRepository *self,
GTypelib *typelib;
GError *error;
- if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|sO:Repository.require",
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|zO:Repository.require",
kwlist, &namespace_, &version, &lazy)) {
return NULL;
}
@@ -207,25 +208,55 @@ _wrap_g_irepository_get_typelib_path (PyGIRepository *self,
return NULL;
}
- return PyString_FromString (typelib_path);
+ return PYGLIB_PyBytes_FromString (typelib_path);
+}
+
+static PyObject *
+_wrap_g_irepository_get_version (PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", NULL };
+ const char *namespace_;
+ const gchar *version;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+ "s:Repository.get_version", kwlist, &namespace_)) {
+ return NULL;
+ }
+
+ version = g_irepository_get_version (self->repository, namespace_);
+ if (version == NULL) {
+ PyErr_Format (PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
+ return NULL;
+ }
+
+ return PYGLIB_PyUnicode_FromString (version);
}
static PyMethodDef _PyGIRepository_methods[] = {
+ { "enumerate_versions", (PyCFunction) _wrap_g_irepository_enumerate_versions, METH_VARARGS | METH_KEYWORDS },
{ "get_default", (PyCFunction) _wrap_g_irepository_get_default, METH_STATIC | METH_NOARGS },
{ "require", (PyCFunction) _wrap_g_irepository_require, METH_VARARGS | METH_KEYWORDS },
{ "get_infos", (PyCFunction) _wrap_g_irepository_get_infos, METH_VARARGS | METH_KEYWORDS },
{ "find_by_name", (PyCFunction) _wrap_g_irepository_find_by_name, METH_VARARGS | METH_KEYWORDS },
{ "get_typelib_path", (PyCFunction) _wrap_g_irepository_get_typelib_path, METH_VARARGS | METH_KEYWORDS },
+ { "get_version", (PyCFunction) _wrap_g_irepository_get_version, METH_VARARGS | METH_KEYWORDS },
{ NULL, NULL, 0 }
};
void
_pygi_repository_register_types (PyObject *m)
{
- PyGIRepository_Type.ob_type = &PyType_Type;
+ Py_TYPE(&PyGIRepository_Type) = &PyType_Type;
+
+ PyGIRepository_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+ PyGIRepository_Type.tp_methods = _PyGIRepository_methods;
+
if (PyType_Ready (&PyGIRepository_Type)) {
return;
}
+
if (PyModule_AddObject (m, "Repository", (PyObject *) &PyGIRepository_Type)) {
return;
}
diff --git a/gi/pygi-struct.c b/gi/pygi-struct.c
index 2f1ce42..c2e1f4d 100644
--- a/gi/pygi-struct.c
+++ b/gi/pygi-struct.c
@@ -25,19 +25,28 @@
#include <pygobject.h>
#include <girepository.h>
+#include <pyglib-python-compat.h>
static void
_struct_dealloc (PyGIStruct *self)
{
+ GIBaseInfo *info = _pygi_object_get_gi_info (
+ (PyObject *) self,
+ &PyGIStructInfo_Type);
+
PyObject_GC_UnTrack ( (PyObject *) self);
PyObject_ClearWeakRefs ( (PyObject *) self);
- if (self->free_on_dealloc) {
+ if (info != NULL && g_struct_info_is_foreign ( (GIStructInfo *) info)) {
+ pygi_struct_foreign_release (info, ( (PyGPointer *) self)->pointer);
+ } else if (self->free_on_dealloc) {
g_free ( ( (PyGPointer *) self)->pointer);
}
- ( (PyGPointer *) self)->ob_type->tp_free ( (PyObject *) self);
+ g_base_info_unref (info);
+
+ Py_TYPE( (PyGPointer *) self )->tp_free ( (PyObject *) self);
}
static PyObject *
@@ -48,7 +57,6 @@ _struct_new (PyTypeObject *type,
static char *kwlist[] = { NULL };
GIBaseInfo *info;
- gboolean is_simple;
gsize size;
gpointer pointer;
PyObject *self = NULL;
@@ -92,41 +100,7 @@ _struct_init (PyObject *self,
return 0;
}
-
-PyTypeObject PyGIStruct_Type = {
- PyObject_HEAD_INIT (NULL)
- 0,
- "gi.Struct", /* tp_name */
- sizeof (PyGIStruct), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) _struct_dealloc, /* tp_dealloc */
- (printfunc) NULL, /* tp_print */
- (getattrfunc) NULL, /* tp_getattr */
- (setattrfunc) NULL, /* tp_setattr */
- (cmpfunc) NULL, /* tp_compare */
- (reprfunc) NULL, /* tp_repr */
- NULL, /* tp_as_number */
- NULL, /* tp_as_sequence */
- NULL, /* tp_as_mapping */
- (hashfunc) NULL, /* tp_hash */
- (ternaryfunc) NULL, /* tp_call */
- (reprfunc) NULL, /* tp_str */
- (getattrofunc) NULL, /* tp_getattro */
- (setattrofunc) NULL, /* tp_setattro */
- NULL, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- NULL, /* tp_doc */
- (traverseproc) NULL, /* tp_traverse */
- (inquiry) NULL, /* tp_clear */
- (richcmpfunc) NULL, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc) NULL, /* tp_iter */
- (iternextfunc) NULL, /* tp_iternext */
- NULL, /* tp_methods */
- NULL, /* tp_members */
- NULL, /* tp_getset */
- (PyTypeObject *) NULL, /* tp_base */
-};
+PYGLIB_DEFINE_TYPE("gi.Struct", PyGIStruct_Type, PyGIStruct);
PyObject *
_pygi_struct_new (PyTypeObject *type,
@@ -158,10 +132,13 @@ _pygi_struct_new (PyTypeObject *type,
void
_pygi_struct_register_types (PyObject *m)
{
- PyGIStruct_Type.ob_type = &PyType_Type;
+ Py_TYPE(&PyGIStruct_Type) = &PyType_Type;
PyGIStruct_Type.tp_base = &PyGPointer_Type;
PyGIStruct_Type.tp_new = (newfunc) _struct_new;
PyGIStruct_Type.tp_init = (initproc) _struct_init;
+ PyGIStruct_Type.tp_dealloc = (destructor) _struct_dealloc;
+ PyGIStruct_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE);
+
if (PyType_Ready (&PyGIStruct_Type))
return;
if (PyModule_AddObject (m, "Struct", (PyObject *) &PyGIStruct_Type))
diff --git a/gi/pygi-type.c b/gi/pygi-type.c
index bd9804e..129ea98 100644
--- a/gi/pygi-type.c
+++ b/gi/pygi-type.c
@@ -25,17 +25,13 @@
PyObject *
-_pygi_type_import_by_gi_info (GIBaseInfo *info)
+_pygi_type_import_by_name (const char *namespace_,
+ const char *name)
{
- const gchar *namespace_;
- const gchar *name;
gchar *module_name;
PyObject *py_module;
PyObject *py_object;
- namespace_ = g_base_info_get_namespace (info);
- name = g_base_info_get_name (info);
-
module_name = g_strconcat ("gi.repository.", namespace_, NULL);
py_module = PyImport_ImportModule (module_name);
@@ -74,6 +70,13 @@ pygi_type_import_by_g_type_real (GType g_type)
}
PyObject *
+_pygi_type_import_by_gi_info (GIBaseInfo *info)
+{
+ return _pygi_type_import_by_name (g_base_info_get_namespace (info),
+ g_base_info_get_name (info));
+}
+
+PyObject *
_pygi_type_get_from_g_type (GType g_type)
{
PyObject *py_g_type;
diff --git a/gi/pygi-type.h b/gi/pygi-type.h
index 16d5bdc..bb43d19 100644
--- a/gi/pygi-type.h
+++ b/gi/pygi-type.h
@@ -33,6 +33,8 @@ PyObject *pygi_type_import_by_g_type_real (GType g_type);
/* Private */
+PyObject *_pygi_type_import_by_name (const char *namespace_, const char *name);
+
PyObject *_pygi_type_import_by_gi_info (GIBaseInfo *info);
PyObject *_pygi_type_get_from_g_type (GType g_type);
diff --git a/gi/pygi.h b/gi/pygi.h
index 0a8cbf5..d1eaf05 100644
--- a/gi/pygi.h
+++ b/gi/pygi.h
@@ -22,6 +22,7 @@
#ifndef __PYGI_H__
#define __PYGI_H__
+#define NO_IMPORT_PYGOBJECT
#include <config.h>
#include <pygobject.h>
@@ -51,23 +52,27 @@ typedef struct {
gsize size;
} PyGIBoxed;
-typedef PyObject * (*PyGIArgOverrideToGArgumentFunc) (PyObject *value,
+typedef PyObject * (*PyGIArgOverrideToGIArgumentFunc) (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
- GArgument *arg);
-typedef PyObject * (*PyGIArgOverrideFromGArgumentFunc) (GITypeInfo *type_info,
- GArgument *arg);
-typedef PyObject * (*PyGIArgOverrideReleaseGArgumentFunc) (GITransfer transfer,
- GITypeInfo *type_info,
- GArgument *arg);
+ GIArgument *arg);
+typedef PyObject * (*PyGIArgOverrideFromGIArgumentFunc) (GITypeInfo *type_info,
+ GIArgument *arg);
+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,
+ const gchar *attr_name);
+ gint (*set_property_value) (PyGObject *instance,
+ const gchar *attr_name,
+ PyObject *value);
void (*register_foreign_struct) (const char* namespace_,
const char* name,
- PyGIArgOverrideToGArgumentFunc to_func,
- PyGIArgOverrideFromGArgumentFunc from_func,
- PyGIArgOverrideReleaseGArgumentFunc release_func);
+ PyGIArgOverrideToGIArgumentFunc to_func,
+ PyGIArgOverrideFromGIArgumentFunc from_func,
+ PyGIArgOverrideReleaseFunc release_func);
};
static struct PyGI_API *PyGI_API = NULL;
@@ -97,11 +102,32 @@ pygi_type_import_by_g_type (GType g_type)
}
static inline PyObject *
+pygi_get_property_value (PyGObject *instance,
+ const gchar *attr_name)
+{
+ if (_pygi_import() < 0) {
+ return NULL;
+ }
+ return PyGI_API->get_property_value(instance, attr_name);
+}
+
+static inline gint
+pygi_set_property_value (PyGObject *instance,
+ const gchar *attr_name,
+ PyObject *value)
+{
+ if (_pygi_import() < 0) {
+ return -1;
+ }
+ return PyGI_API->set_property_value(instance, attr_name, value);
+}
+
+static inline PyObject *
pygi_register_foreign_struct (const char* namespace_,
const char* name,
- PyGIArgOverrideToGArgumentFunc to_func,
- PyGIArgOverrideFromGArgumentFunc from_func,
- PyGIArgOverrideReleaseGArgumentFunc release_func)
+ PyGIArgOverrideToGIArgumentFunc to_func,
+ PyGIArgOverrideFromGIArgumentFunc from_func,
+ PyGIArgOverrideReleaseFunc release_func)
{
if (_pygi_import() < 0) {
return NULL;
@@ -122,6 +148,21 @@ pygi_type_import_by_g_type (GType g_type)
return NULL;
}
+static inline PyObject *
+pygi_get_property_value (PyGObject *instance,
+ const gchar *attr_name)
+{
+ return -1;
+}
+
+static inline gint
+pygi_set_property_value (PyGObject *instance,
+ const gchar *attr_name,
+ PyObject *value)
+{
+ return -1;
+}
+
#endif /* ENABLE_INTROSPECTION */
#endif /* __PYGI_H__ */
diff --git a/gi/repository/Makefile.in b/gi/repository/Makefile.in
index 3252c9d..7b36c15 100644
--- a/gi/repository/Makefile.in
+++ b/gi/repository/Makefile.in
@@ -115,6 +115,7 @@ GIOUNIX_LIBS = @GIOUNIX_LIBS@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
GI_CFLAGS = @GI_CFLAGS@
+GI_DATADIR = @GI_DATADIR@
GI_LIBS = @GI_LIBS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
diff --git a/gi/types.py b/gi/types.py
index 8ac9cab..0a8768c 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -50,7 +50,7 @@ def Constructor(info):
def constructor(cls, *args):
cls_name = info.get_container().get_name()
if cls.__name__ != cls_name:
- raise TypeError, '%s constructor cannot be used to create instances of a subclass' % cls_name
+ raise TypeError('%s constructor cannot be used to create instances of a subclass' % cls_name)
return info.invoke(cls, *args)
constructor.__info__ = info
@@ -105,10 +105,14 @@ class MetaClassHelper(object):
'the method do_%s()' % (base.__info__.get_namespace(),
base.__info__.get_name(),
vfunc_info.get_name()))
- elif vfunc is not None and not \
- is_function_in_classes(vfunc.im_func, cls.__bases__):
- hook_up_vfunc_implementation(vfunc_info, cls.__gtype__,
- vfunc)
+ elif vfunc is not None:
+ function = vfunc
+ if sys.version_info < (3, 0):
+ function = vfunc.im_func
+
+ if not is_function_in_classes(function, cls.__bases__):
+ hook_up_vfunc_implementation(vfunc_info, cls.__gtype__,
+ vfunc)
def is_function_in_classes(function, classes):
for klass in classes:
@@ -161,6 +165,7 @@ class StructMeta(type, MetaClassHelper):
def override(type_):
g_type = type_.__info__.get_g_type()
+ assert g_type != gobject.TYPE_NONE
if g_type != gobject.TYPE_INVALID:
g_type.pytype = type_
return type_