summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2010-04-20 17:03:38 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2010-04-20 17:03:38 -0400
commitdca2aa52fd0a1cc95eb486ce00f330884a14dc7e (patch)
tree5545049f9f974c6099e623962e9fcce0c8a77aad
parent205ba7d43e29c82580d75c302fee5c2632391da0 (diff)
downloadpygi-py3k.tar.gz
pygi-py3k.tar.xz
pygi-py3k.zip
Manually type-check the instance variable during method invocations on Python 3HEADpy3k
-rw-r--r--gi/pygi-info.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 6f89e51..454b06c 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -710,6 +710,65 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
g_assert(py_args_pos == n_py_args);
}
+#if PY_MAJOR_VERSION >= 3
+ if (is_method) {
+ /*
+ In Python 2, type-checking of the instance is done for us by
+ Objects/classobject.c:instancemethod_call, which will raise
+ a TypeError of the form
+ "unbound method %s%s must be called with "
+ "%s instance as first argument "
+ "(got %s%s instead)",
+
+ In Python 3, it appears that this checking isn't done for us,
+ so we do it here:
+ */
+ GIBaseInfo *container_info;
+ PyObject *py_expected_type;
+ PyObject *py_arg;
+ int is_instance;
+
+ container_info = g_base_info_get_container(self->info);
+ py_expected_type = _pygi_type_import_by_gi_info (container_info);
+
+ if (py_expected_type == NULL) {
+ goto out;
+ }
+
+ py_arg = PyTuple_GetItem(py_args, 0);
+ if (py_arg == NULL) {
+ Py_DECREF(py_expected_type);
+ goto out;
+ }
+
+ is_instance = PyObject_IsInstance(py_arg, py_expected_type);
+ if (is_instance == -1) {
+ Py_DECREF(py_expected_type);
+ goto out;
+ }
+
+ if (is_instance == 0) {
+ gchar *type_name_expected;
+
+ type_name_expected = _pygi_g_base_info_get_fullname(container_info);
+
+ PyErr_Format(PyExc_TypeError,
+ "method must be called with "
+ "%s instance as first argument "
+ "(got %s instead)",
+ type_name_expected,
+ py_arg->ob_type->tp_name
+ );
+
+ g_free(type_name_expected);
+
+ Py_DECREF(py_expected_type);
+ goto out;
+ }
+ Py_DECREF(py_expected_type);
+ }
+#endif
+
args = g_newa(GArgument *, n_args);
in_args = g_newa(GArgument, n_in_args);
out_args = g_newa(GArgument, n_out_args);